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

时间:2014-07-30 09:07:40

标签: c++ encapsulation abstraction

我想保留封装和抽象,但我真的很难编辑它。我在C中完成了这个程序并且它工作但是将它转换为OOP对我来说真的很头疼。该程序是一个.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时遇到问题,所以我猜我的做法并不是很好。

2 个答案:

答案 0 :(得分:2)

使用C++ standard library为您提供的功能,您可以大大简化代码。

班级定义:

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::unordered_map以及类型扣除的auto关键字和用于创建类型别名的using关键字在C ++ 11中都是新的。它得到了所有主要编译器最新版本的支持(在GCC和Clang的情况下,不是最新的版本)。

答案 1 :(得分:1)

XIniFile::open(const char *fn)调用addKey,它不是自由函数或XIniFile的成员。这就是编译器出错的原因。

一些一般设计说明:

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