我有一个类Base1,它包含一个不同类Base2的对象数组。我想有一个派生类Derived1继承Base1中的所有东西,除了数组是Derived2类型(它是Base2的派生类)。例如,像这样:
class Base2{
int a2;
};
class Derived2: public Base2{
int b2;
};
class Base1{
Base2* list;
};
class Derived1: public Base1{
Derived2* list;
};
我的理解是,在上面的例子中,Derived1的一个对象实际上有两个数组:
list
和
Base1::list
我不想要。
这个想法是Base1的所有功能仍然适用于Derived1对象,因为Derived2“是一个”Base2。它真的很脏,但我想我可以在Derived1构造函数中删除[] Base1 :: list数组。
有没有人看到这个解决方案?这似乎是经常发生的事情,我无法相信一个简单的解决方案不存在。使用模板会起作用吗?我的想法是否定的,因为Base1和Derived1中的所有功能都需要知道它们分别处理Base2和Derived2对象。
答案 0 :(得分:2)
当有人将Derived1
课程转发到Base1
时,您会发生什么?在破坏基类后使用list
时会崩溃。最好的方法是继续使用基类list
,并确保只将Derived2
类型的对象放入列表中。如果列表的内容无法进行外部修改,那么这将是有效的并且是安全的。
是的,我知道还有很多话要说,但让我们一步一步。
答案 1 :(得分:2)
在一般情况下,你想做什么似乎很危险,但我认为你知道风险;)
我可以建议两种解决方案:
选项1:
您可以隐藏protected
部分中的实际指针并提供访问功能。
class Base1 {
protected:
void *ptr
public:
Base2 *list() {return (Base2*)ptr;}
};
class Derived1 : public Base1 {
public:
Derived2 *list() {return (Derived2*)ptr;}
};
基本上,Base2::list
将隐藏Derived2::list
。请注意,您无法使它们虚拟化并从虚拟化中受益。必须在编译时知道返回类型。
选项2:
您可以使用模板化基类。
template <typename T>
class List {
public:
T *list
//implement all functionality which is common, regardless of the type T
};
class Base1 : public List<Base2> {
//specifics for Base2 type
};
class Derived1 : public List<Derived2> {
//specifics for Derived2
};
请注意,在此构造中,Base1和Derived1不是直接相关的,而是具有共同的祖先。
答案 2 :(得分:1)
我将从Base1中删除Base2数组,并使用列表创建一个新类:
class Base2{
int a2;
};
class Derived2: public Base2{
int b2;
};
class Base1{
};
class Base1WithList : public Base1{
Base2* list;
};
class Derived1: public Base1{
Derived2* list;
};
答案 3 :(得分:1)
我认为没有什么简单可以解决你的问题。
我会使用以下方法之一 -
选项1 将Base2 *列表(在base1类中)隐藏为私有,并将其保存为派生类(derived1)继承。当然,在base1类中定义一个getter函数来访问列表。
选项2 只需将base1类中的列表类型更改为(指向Derived2的指针),并依赖于指向派生类的指针与指向其基类的指针类型兼容的事实。
选项3 忘记继承并使用模板。您只需在实例化对象时指定类型(Base2 *或Derived2 *),生活就会再次美丽。