目录结构 - 文件和文件夹类应该相互了解?

时间:2013-04-28 11:49:12

标签: c++ class inheritance class-hierarchy

当我尝试创建类似于此的目录结构时,我遇到了两个相互了解的问题:

Directory structure example

这是我的Base课程,其中包含FileFolder的常见元素。 请注意,为了这个问题,我已经省略了getter和setter,构造函数和析构函数,#include#define以及其他非相关的方法和属性(=几乎所有内容):

class Base {
    private:
        string m_name;
        /* Both File and Folder have a parent,
         * but the parent can only be a Folder */
        Base* m_parent;
};

这是可以正常使用的课程Folder

class Folder : public Base {
    public:
        virtual void addChild(Base* child);
        virtual void removeChild(Base* child);
    private:
        vector<Base*> m_children;
};

然后File类没有什么新内容(除了一些与我的问题无关的文件相关内容,所以我把它们遗漏了):

class File : public Base {
};

现在头文件看起来还不错,没什么奇怪的。 但是,这就是我的构造函数应该是这样的:

Base::Base(string name, Base* parent) { ... }
File::File(string name, Base* parent) { ... }
// parent should be of type Folder for Files too
Folder::Folder(string name, Folder* parent) { ... }

问题很明显。 首先,父母应该始终是Folder,它不能是File。 但是,我必须使用Base,因为FileBase显然无法知道Folder

此外,由于我的BaseFile不知道Folder,因此无法将其称为addChild(Base* child);方法:

File::File(string name, Base* parent)
: m_name(name), m_parent(parent)
{
    if (parent) {
        parent->addChild(this); // Base doesn't have addChild()-method
    }
}

我开始思考,我怎么能解决这个问题呢?

编辑:我不想要一个hacky方式来获得我正在寻找的结果,我想找到我设计中的错误。 这个东西是如何为windows或unix设计的?

1 个答案:

答案 0 :(得分:4)

试试这个:

class Folder;

class Base {
    protected:
        Base(const string &name, Folder *parent);
    private:
        string m_name;
        Folder *m_parent;
    //no add or remove should go here
};

class Folder : public Base {
    public:
        Folder(const string &name, Folder *parent)
        :Base(name, parent)
        {
        }
        void addChild(Base* child);
        void removeChild(Base* child);
    /*...*/
};

class File : public Base {
    public:
        File(const string &name, Folder *parent)
        :Base(name, parent)
        {
        }
};

inline Base::Base(const string &name, Folder *parent);
:m_name(name), m_parent(parent)
{
    if (parent) {
        parent->addChild(this); // no problem!
    }
}