假设您有一个具有多个功能的基类,例如
virtual int func1();
virtual int func2();
virtual int func3();
virtual int func4();
等
你想要有两个子类,Child1和Child2。 Child1可以包含func1()和func2()但不包含func3()或func4(),而Child2包含func3()和func4()但不包含func1()或func2()?
所以Child1会包含:
int func1()
int func2()
而Child2将包含:
int func3()
int func4()
我问,因为我试图做这样的事情,但是当我尝试运行它时,我总是在整个地方得到未定义的引用错误。例如,会出现如下错误:
/tmp/cczUiDZ2.o:(.rodata._ZTV5Child1[_ZTV5Child1]+0x38): undefined reference to `Parent::func3()'
答案 0 :(得分:1)
假设您有一个具有多个功能的基类,例如
virtual int func1();
virtual int func2();
virtual int func3();
virtual int func4();
即使没有提及派生类,也存在潜在问题。您已声明Base::func1()
等,但尚未定义这些功能。这就是链接器错误所抱怨的。
如果在基类级别定义这些函数没有意义,则需要通过在终止函数声明的分号之前插入= 0
来将这些函数声明为“纯虚拟”:
class Base {
public:
virtual int func1() = 0;
virtual int func2() = 0;
virtual int func3() = 0;
virtual int func4() = 0;
...
};
(注意:我故意公开这些纯虚函数。我稍后会讨论。)
这样做可以说这些函数可以用于从基类派生的任何类,但同时,在这些函数中定义这些函数是没有意义的。基类级别。如果这样做,那么必须在子类(或子子类或子...子子类)中定义这些函数。具有未定义的纯虚函数的类不可实例化。
如果您希望Child1
具有[{1}}和func1()
功能,而不是func2()
或func3()
,该怎么办?这些函数可以在基类级别调用,但不能在子类级别调用。这违反了Liskov substitution principle。这是一个非常重要的信号,表明你的设计是错误的。
另一种方法是在基类级别(有意义的地方)提供默认实现,并在子类级别覆盖它们(这是有意义的)。您的func4()
可以提供Child1
和func1()
的特定于类的定义,这些定义会覆盖基类中提供的默认值。
另一种替代方法是使用多重继承。多重继承会让你陷入深深的麻烦,但是做得对,多重继承并没有错。
另一种选择是做一些颠覆但不违反Liskov替代的事情。例如,在func2()
中实现func3()
和func4()
,但始终在这些实现中引发异常。不要这样做。
答案 1 :(得分:0)
你无法达到你所要求的,即一个没有"和#34;一个基类的功能,而另一个孩子正在使用它。但是,从你的例子中,我看到你可能意味着不同的东西。让我们看看下面的例子:
class Parent
{
virtual int func1() = 0;
virtual int func2()
{ return 0; }
};
class Child: public Parent
{
int func1()
{ return 0; }
};
int main()
{
Child c;
}
在此示例中,类Child
不会覆盖虚拟func2
。但是,您可以看到Parent
类提供了自己的定义,将用作"默认"在这种情况下。