纯虚函数与实现
我的基本理解是,没有一个纯虚函数的实现,但是,我被告知可能有纯虚函数的实现。
class A { public: virtual void f() = 0; }; void A::f() { cout<<"Test"<<endl; }
代码是否高于OK?
有什么目的,使它成为一个纯虚函数的实现?
纯virtual
函数必须在直接实例化的派生types中实现,但是基types仍然可以定义实现。 如果A::f()
是public
或protected
),派生类可以通过使用全范围名称(通过在示例中调用A::f()
来显式调用基类实现(如果访问权限允许的话)。 就像是:
class B : public A { virtual void f() { // class B doesn't have anything special to do for f() // so we'll call A's // note that A's declaration of f() would have to be public // or protected to avoid a compile time problem A::f(); } };
我能想到的用例就是当有一个或多或less合理的默认行为时,但是类devise者只需要明确地调用这种默认行为。 也可以是你希望派生类总是执行自己的工作,但也能够调用一组通用的function。
请注意,虽然语言允许,但这并不是我常见的东西(事实上它可以做到似乎让大多数C ++程序员感到惊讶,甚至是经验丰富的)。
要清楚,你误解了什么= 0; 之后是虚拟function的意思。
= 0表示派生类必须提供实现,而不是基类不能提供实现。
实际上,当你将一个虚拟函数标记为纯粹的(= 0)时,提供一个定义是没有意义的,因为除非有人通过Base :: Function(…)明确地这样做,基类构造函数调用有问题的虚函数。
它的优点是它强制派生types仍然覆盖该方法,但也提供了一个默认或附加的实现。
如果你有代码应该由派生类执行,但你不希望它被直接执行 – 你想强制它被重写。
你的代码是正确的,尽pipe总之这并不是一个常用的function,通常只有在试图定义一个纯粹的虚拟析构函数的时候才会出现 – 在这种情况下,你必须提供一个实现。 有趣的是,一旦你从该类派生,你不需要重写析构函数。
因此,纯虚函数的一个明智用法就是将纯虚析构函数指定为“非最终”关键字。
下面的代码是令人惊讶的正确的:
class Base { public: virtual ~Base() = 0; }; Base::~Base() {} class Derived : public Base {}; int main() { // Base b; -- compile error Derived d; }
你必须给一个纯粹的虚拟析构函数的身体,例如:)
阅读: http : //cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(链接中断,使用存档)
是的,这是正确的。 在你的例子中,派生自A的类inheritance了接口f()和默认实现。 但是你强迫派生类来实现方法f()(即使它只是调用A提供的默认实现)。
Scott Meyers在Effective C ++(第2版)中对此进行了讨论。Item#36区分接口的inheritance和实现的inheritance。 产品编号在最新版本中可能已更改。
具有或不具有主体的纯虚拟函数仅仅意味着派生types必须提供它们自己的实现。
如果您的派生类想要调用您的基类实现,则基类中的纯虚函数体是有用的。
'virtual void foo()= 0;' 语法并不意味着你不能在当前类中实现foo(),你可以。 这也并不意味着你必须在派生类中实现它 。 在给我打耳光之前,让我们来观察钻石问题:(隐含的代码,介意你)。
class A { public: virtual void foo()=0; virtual void bar(); } class B : public virtual A { public: void foo() { bar(); } } class C : public virtual A { public: void bar(); } class D : public B, public C {} int main(int argc, const char* argv[]) { A* obj = new D(); **obj->foo();** return 0; }
现在,obj-> foo()调用将导致B :: foo()和C :: bar()。
你可以看到……纯粹的虚拟方法不必在派生类中实现(foo()在类C中没有实现 – 编译器会编译)在C ++中有很多漏洞。
希望我能帮助:-)