从另一个对象访问一个对象的方法(有更好的方法吗?)

Accessing methods of an object from another object (Suggest for a better approach?)

本文关键字:一个对象 方法 更好 访问      更新时间:2023-10-16

我想保留封装和抽象,但我真的有麻烦编辑这个。我用C写了这个程序,它可以工作,但是把它转换成面向对象对我来说真的很头疼。这个程序是一个。ini文件阅读器,格式如下:

[sections] keys = values

XKey::XKey(const char *k, const char *v)
{
    free(m_name);
    free(m_value);
    m_name = strdup(k);
    m_value = strdup(v);
    m_next = 0;
}
XKey *XSection::addKey(const char *k, const char *v)
{
    XKey *kn = new XKey(k, v);
    XKey *ks;
    if (m_keys == 0) {
        m_keys = kn;
        return kn;
    }
    ks = m_keys;
    while (ks->m_next)
        ks = ks->m_next;
    ks->m_next = kn;
    return kn;
}
XKey::~XKey()
{
}
XSection::XSection(const char *s)
{
   free(m_name);
   m_name = strdup(s);
   m_next = 0;
   m_keys = 0;
}
XSection *XIniFile::addSection(const char *d)
{
    XSection *sn = new XSection(d);
    XSection *ss;
    if (m_sections == 0) {
        m_sections = sn;
        return sn;
    }
    ss = m_sections;
    while(ss->m_next)
        ss = ss->m_next;
    ss->m_next = sn;
    return sn;
}
XSection::~XSection()
{
}
XIniFile::XIniFile()
{
    m_sections = 0;
    m_modified = FALSE;
}
int XIniFile::open(const char *fn)
{   
    //do some routines here to get string values for 
    //sn               <--section name
    //kn               <--key name
    //val               <--value name
    //do loop here to insert all the sections   
            cs = addSection(sn);
            //do loop here to add all the keys and values on every section 
            //then move to the next section    
                addKey(kn, val);    
    return 0;
}
XIniFile::~XIniFile()
{
}

这是我的。h文件的一个片段

class XKey
{
    friend class XSection;
    friend class XIniFile;
public:
    XKey(const char *, const char *);
    virtual ~XKey();
private:
    char *m_name;
    char *m_value;
    XKey *m_next;
};
class XSection
{
    friend class XIniFile;
public:
    XSection(const char *);
    XKey *addKey(const char *, const char *);
    virtual ~XSection();   
private:    
    char *m_name;
    XKey *m_keys;
    XSection *m_next;
};
class XIniFile
{
private:
    char *m_name;
    XSection *m_sections;
    int m_modified;
    XSection *addSection(const char *);
public:
    XIniFile();
    virtual ~XIniFile();
};

我希望你能理解我正在做的程序。基本上我只是把它们存储在一个链表中。

我有这个错误addKey was not declared in this scope的问题,所以我想我的方法不是很好。

使用c++标准库提供的功能,可以大大简化代码。

类定义:
class XIniFile
{
public:
    // Get a value
    std::string get(const std::string& section,
                    const std::string& key,
                    const std::string& dflt = "") const;
    // Set a value
    void set(const std::string& section,
             const std::string& key,
             const std::string& data);
private:
    // Type alias to map a key to data inside a section
    using key_data_map_t = std::unordered_map<std::string, std::string>;
    // Type alias to map a section to a set of key-data pairs
    using section_map_t = std::unordered_map<std::string, key_data_map_t>;
    section_map_t sections;
};

代码:

std::string XIniFile::get(const std::string& section,
                          const std::string& key,
                          const std::string& dflt /* = "" */)
{
    auto section_iter = sections.find(section);
    if (section_iter != sections.end())
    {
        // Section found
        auto key_data_iter = section_iter->second.find(key);
        if (key_data_iter != section_iter->second.end())
        {
            // Key found
            return key_data_iter->second;
        }
    }
    // Section or key not found, return default value
    return dflt;
}
void XIniFile::set(const std::string& section,
                   const std::string& key,
                   const std::string& data)
{
    sections[section][key] = data;
}

引用:

  • std::string
  • std::unordered_map

注释: std::unordered_map以及用于类型推导的auto关键字和用于创建类型别名的using关键字都是c++ 11中新增的。所有主要编译器的最新版本都支持它(在GCC和Clang的情况下,不是最新的)。

XIniFile::open(const char *fn)调用addKey,这不是一个自由函数,也不是XIniFile的成员。这就是为什么你会得到编译错误。

一般设计注意事项:

    尽量不要使用友类或函数,因为它们会破坏封装。使用公共接口
  • 使用c++类代替C类型的字符串,向量(而不是数组)
  • 为什么所有的类都有虚析构函数?它们没有任何虚方法,所以它们不适合作为基类
  • 使用c++类型代替C类型,例如c++ bool代替int和FALSE
  • 使用RAII包装器代替手动显式堆分配对象。vector代替new[], unique_ptr或shared_ptr等