5

我有一个抽象基类,想在派生类中实现一个函数。为什么我必须在派生类中再次声明函数?

class base {
public:
    virtual int foo(int) const = 0;
};

class derived : public base {
public:
    int foo(int) const; // Why is this required?
};

int derived::foo(int val) const { return 2*val; }
4

6 回答 6

7

考虑派生类定义可能位于标头中,而其实现可能位于源文件中。标头通常包含在多个位置(“翻译单元”)中,每个位置都将独立编译。如果您没有声明覆盖,那么编译器将不会在任何其他翻译单元中知道它。

于 2012-06-27T09:10:22.320 回答
4

在基类中制作纯函数的目的virtual是派生类必须覆盖它并提供自己的实现。
请注意,类中存在纯虚函数使该类成为抽象类。简单来说,类充当创建更具体类的接口。不能创建抽象类的对象。

如果你不重写派生类中的纯虚函数,那么派生类只包含继承的基类纯虚函数,它本身也充当抽象类。一旦你的派生类是抽象的,它就不能被实例化。
因此,为了实例化您的派生类,它需要重写并因此声明纯虚函数。

于 2012-06-27T09:08:55.973 回答
2

您可能认为编译器可以推断出您将必须提供 的实现derived::foo(),但derived也可能是一个抽象类(事实上,如果您不声明foo()in ,您将得到这样的结果derived

于 2012-06-27T09:11:43.737 回答
1

It is to override the abstraction of the base class.

如果你不重新声明它,那么你的派生类也是一个抽象类。如果你这样做了,那么你现在有一个非抽象类型的基础。

于 2012-06-27T09:11:34.477 回答
1

因为层次结构可以有更多层。

struct Base {
    virtual void foo() const = 0;
    virtual void bar() const = 0;
};

struct SuperBase: Base {
     virtual void bar() const override;
};

struct Concrete: SuperBase {
     virtual void foo() const override;
};

在这里,SuperBase不提供实现foo,这需要以某种方式指示。

于 2012-06-27T09:30:14.907 回答
1

虽然你不能用纯虚函数实例化一个类,你仍然可以像这样创建一个类:

class base {
public:
    virtual int foo(int) const = 0;
};

class derived : public base {
public:
};

class very_derived : public derived {
public:
    virtual int foo(int) const { return 2; }
};

派生类仍然是一个抽象类,它不能被实例化,因为它没有覆盖foo。在实例化类之前,您需要声明 foo 的非纯虚拟版本,即使您没有立即定义 foo。

于 2012-06-27T09:33:26.813 回答