之前可能已经回答过,但我找不到这些词。
我试图在C++
中围绕继承,但是来自C#
我似乎无法理解以下案例背后的原因:
Foo.h
class Foo {
virtual void DoSomething();
}
class Bar : Foo { }
Bar.cpp
#include "Foo.h"
void Bar::DoSomething()
{
//Compiler error C2509 - member function not declared in 'Bar'
}
由于DoSomething
是一个纯虚函数,所以它是否可以隐含地被声明为Bar
的一部分?
如果我有许多继承自Foo
的不同类,我是否真的需要在每一类中明确声明DoSomething
?
C++
中还有哪些其他结构可以处理这种情况?
答案 0 :(得分:10)
C ++语言建立在与独立翻译相同的原则上。这意味着C ++程序中的所有翻译单元应该完全相互独立地编译。当编译器本身已经完成工作时,它们链接到最后的程序。
对于类,为了能够独立编译每个翻译单元,编译器必须能够通过查看类的定义来建立对给定类的充分理解单独,即通常放在头文件中的部分。在编译一个翻译单元时,编译器必须知道DoSomething
中的Bar
被覆盖,void Bar::DoSomething()
的定义存在于某个其他翻译单元中。为了实现这一点,类定义必须包含所有类成员函数的声明。
关于“纯虚函数”的推理对我来说完全不清楚。首先,它在您的代码示例中并不纯粹(显然您只是忘记了= 0
部分)。其次,仅仅因为基类函数是纯粹的并不意味着派生类函数应该是非纯的。 Bar
很可能也应该是一个抽象类。这是你的意图问题,编译器不知道。
答案 1 :(得分:3)
Bar
的定义是大多数代码都会知道的。其他翻译单元不会看到“Bar.cpp”,但仍需要生成Bar
个实例的正确内存表示,包括Bar
的vtable。这意味着他们需要知道Bar是否真的覆盖Foo::DoSomething
,因为内存中的表示会因此而异。
答案 2 :(得分:2)
是的,您需要明确声明此方法。来自C#,你会注意到C ++并没有“掌握”很多东西。我并不是故意侮辱,但是C ++迫使你在所做的每一件事上都非常明确。