基类是否有可能具有不在派生类中的函数?

时间:2015-05-23 22:25:44

标签: c++ inheritance

假设您有一个具有多个功能的基类,例如

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()'

2 个答案:

答案 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()可以提供Child1func1()的特定于类的定义,这些定义会覆盖基类中提供的默认值。

另一种替代方法是使用多重继承。多重继承会让你陷入深深的麻烦,但是做得对,多重继承并没有错。

另一种选择是做一些颠覆但不违反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类提供了自己的定义,将用作"默认"在这种情况下。