为什么界面需要重新声明?

时间:2012-06-27 09:07:43

标签: c++ inheritance

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

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

6 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

如果你没有覆盖派生类中的纯虚函数,那么派生类只包含继承的Base类纯虚函数,它本身也充当抽象类。一旦你的派生类是抽象的,它就无法实例化。登记/> 因此,为了实例化派生类,它需要覆盖并因此声明纯虚函数。

答案 2 :(得分:2)

您可能认为编译器可以推断出您必须提供derived::foo()的实现,但derived也可能是一个抽象类(实际上这就是您将获得的内容)如果您未在foo())中声明derived

答案 3 :(得分:1)

It is to override the abstraction of the base class

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

答案 4 :(得分: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的实现,需要以某种方式表明。

答案 5 :(得分: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。