基类是否有可能具有不在派生类中的函数?
Is it possible for a base class to have a function that's not in the derived class?
假设您有一个包含多个函数的基类,如
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
类提供了自己的定义,在这种情况下将被用作"默认"。
- 为什么使用 "this" 指针调用派生成员函数?
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 在 C++ 中用派生类型重写成员函数
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 在派生类中绑定非静态模板化成员函数
- 使用 std::variant<...时调用 BaseState 函数而不是派生函数>
- C++:为什么无法在派生类中访问受保护的构造函数?
- C++派生的类构造函数
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 覆盖虚拟函数 - 派生类具有不同的参数
- 正在调用基方法,而不是从构造函数派生方法
- 从具有相同虚拟函数的父函数派生时如何调用子函数
- 从派生类对象调用基类函数.派生类构造函数中设置的基类数据成员