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

Is it possible for a base class to have a function that's not in the derived class?

本文关键字:函数 派生 有可能 是否 基类      更新时间:2023-10-16

假设您有一个包含多个函数的基类,如

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

假设你有一个包含多个函数的基类,比如

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;
  ...
};

(注意:我有意将这些纯虚函数设为public。)

这样做的意思是说这些函数可以在派生自基类的任何类上使用,但同时,在基类级别定义这些函数没有意义。如果这样做,这些函数必须在子类(或子子类,或子…)中定义。-sub-child类)。具有未定义纯虚函数的类是不可实例化的。

如果您希望Child1具有func1()func2()的功能,而不具有func3()func4()的功能,该怎么办?这些函数可以在基类级别调用,但不能在子类级别调用。这违反了利斯科夫替换原则。这是一个非常明显的迹象,表明你的设计是错误的。

另一种选择是在基类级别(这是有意义的)提供默认实现,并在子类级别(这是有意义的)重写它们。您的Child1可以提供func1()func2()的类特定定义,覆盖基类中提供的默认值。

另一种选择是使用多重继承。多重继承可能会给你带来很大的麻烦,但如果处理得当,多重继承并没有什么问题。

另一种选择是做一些颠覆但不违反Liskov替换的事情。例如,在Child1中实现func3()func4(),但在这些实现中总是抛出异常。

你不能实现你字面上的要求,即一个子类不"拥有"一个基类的函数,而另一个子类拥有它。然而,从你的例子中,我看到你可能有不同的意思。让我们看看下面的例子:

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类提供了自己的定义,在这种情况下将被用作"默认"。