为什么没有隐式定义继承

时间:2013-10-01 18:32:59

标签: c++ inheritance virtual-functions

之前可能已经回答过,但我找不到这些词。

我试图在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++中还有哪些其他结构可以处理这种情况?

3 个答案:

答案 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 ++迫使你在所做的每一件事上都非常明确。