【问题标题】:Directory structure - file and folder classes should know each other?目录结构——文件和文件夹类应该互相认识吗?
【发布时间】:2013-04-28 11:49:12
【问题描述】:

当我尝试创建类似这样的目录结构时,遇到了两个类相互认识的问题:

这是我的Base 类,其中包括FileFolder 的公共元素。 请注意,为了这个问题,我省略了 getter 和 setter、构造函数和析构函数、#includes 和 #defines 以及其他不相关的方法和属性(=几乎所有内容):

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 设计的?

【问题讨论】:

  • 那么Base到底有什么用呢?文件夹是你结构中唯一的东西,文件是唯一的具体叶子。为什么他们需要一个共同的基地?
  • 地图不是领土。把遗产扔掉。将文件和文件夹通用的函数包装在一个界面中。
  • @Mat 很抱歉我的回答太晚了,我刚刚遇到其他人遇到同样的问题并记得我的这个问题。他们“需要”一个通用的基类,因为它们 90% 相关,如果他们没有一个通用的基类,我应该如何在文件夹中创建一个向量 m_children?它必须包含两种不同的类型,Files 和 Folders。

标签: c++ class inheritance class-hierarchy


【解决方案1】:

试试这个:

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!
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 2018-11-21
    • 2013-12-15
    相关资源
    最近更新 更多