【发布时间】:2014-11-21 19:56:55
【问题描述】:
编辑:底部的具体示例
解释问题的最佳方式是通过示例(请注意,此特定示例的解决方案不是我要寻找的答案)。
假设我有一个基类Base,它基本上是一个容器:
class Base {
protected:
class BaseNode {
protected:
BaseNode* next;
int id;
};
Node* head;
public:
// ... functionality
};
现在我想派生和改进它,添加一个额外的数据字段:
class Derived : public Base {
private:
class DerivedNode: public BaseNode {
char* name;
};
public:
// .. some more functionality
};
我想要的是一个具有Base 的所有功能的Derived 类,但让每个节点还包含一个name,而不仅仅是一个id。
但如果我查看DerivedNode 的实例,我想要会是:
DerivedNode = {
DerivedNode* next;
int id;
char* name;
};
但我拥有的是:
DerivedNode = {
BaseNode* next;
int id;
char* name;
};
所以DerivedNode()->next->name 将是未定义的!
更不用说Base 类只处理BaseNodes...所有对new 和delete 的调用都不会为DerivedNode 中的char* 分配足够的内存。
这似乎是一个非常普遍的问题,有没有一些巧妙的方法来解决这个问题? Bases 的大部分功能即使对于 DerivedNodes 也非常有用,所以我更愿意保持继承方案原样......
编辑:当这可能有用的具体示例
我真的不想写很多代码,所以我会试着解释一下……如果有人想看一个例子,我已经问了一个关于我的具体需求的问题here。
我正在实现一个List 类。那是我的基类。它是模板化的(每个节点中的数据都是模板化的,每个节点也有 *next 和 *prev 字段),有一个迭代器嵌套类,通过迭代器位置插入、删除……作品。
我想实现一个Forrest 类,它是一个数据节点列表(仍然是模板化的),但每个节点都包含一个指向该节点的TreeNodes 列表。我想这样做是因为数据是可排序的,并且我希望能够在 log(n) 时间(因此是一棵树)中获取它,但它可以通过两种不同的方式(例如年龄和 ID 号)进行排序,所以我需要两棵树指向相同的数据。
所以:我让Forrest 继承自List,并派生ForrestNode 以包含指向数据的TreeNodes 列表:
class DerivedNode: public List<T>::ListNode {
List<Tree<T*>::TreeNode*> treeNodes;
};
基类 List 不需要知道新的 treeNodes 字段,因为它与列表功能无关 - 像 swap、get_head、is_empty 这样的方法应该工作相同,并且创建一个新节点应该几乎相同(需要分配更多内存,但新的treeNodes 字段不应该用数据初始化)。
然而,新的 Forrest 类将覆盖基本的 Lists 方法,但仅限于添加功能 - 例如,在插入(常规列表插入)之后,指针将插入到相关树中,然后新树节点的地址将被添加到treeNodes列表中。
【问题讨论】:
-
如果您真的需要多态性,这将非常困难,但由于您似乎没有使用多态性 (
DerivedNode()->next->name),您可能想看看用模板解决这个问题。 -
你能分享一些这样的设计会有帮助的具体场景吗?
标签: c++ inheritance polymorphism nested-class