我有一个抽象基类,并希望在派生类中实现一个函数。为什么我必须再次在派生类中声明该函数?
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; }
答案 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。