Answers:
纯virtual
函数必须以将直接实例化的派生类型实现,但是基本类型仍可以定义实现。派生类可以显式调用基类的实现(如果访问权限允许的话)使用全范围的名称(通过调用A::f()
在你的榜样-如果A::f()
是public
或protected
)。就像是:
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();
}
};
我可以想到的用例是存在某种或多或少合理的默认行为,但是类设计器希望仅显式调用默认行为。您可能希望派生类始终执行自己的工作,但又能够调用一组通用功能。
请注意,即使该语言允许使用它,也不是我看到的常用语言(而且可以做到这一点似乎令大多数C ++程序员,甚至是经验丰富的程序员都感到惊讶)。
明确地说,您误解了= 0;后虚函数的意思。
= 0表示派生类必须提供实现,而不是基类不能提供实现。
实际上,当您将虚拟函数标记为纯函数(= 0)时,提供定义几乎没有意义,因为除非有人通过Base :: Function(...)明确地进行了定义,否则将永远不会调用该定义。基类构造函数将调用该虚函数。
它的优点是,它强制派生类型仍然覆盖该方法,但还提供默认或附加实现。
如果您有应由派生类执行的代码,但又不想直接执行-则希望强制将其重写。
您的代码是正确的,尽管所有这些都不是经常使用的功能,并且通常仅在尝试定义纯虚拟析构函数时才可见-在这种情况下,您必须提供一个实现。有趣的是,一旦从该类派生,就不需要覆盖析构函数。
因此,纯虚拟函数的一种合理用法是将纯虚拟析构函数指定为“非最终”关键字。
以下代码出奇的正确:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
'虚拟无效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 ++中有很多漏洞。
希望我能帮助:-)
C
在示例中实例化类型的对象。您可以实例化类型的对象,D
因为它foo
从实现了它的实现B
。
deported
。(在.inl或.cpp中指的是常见的文件命名惯例)。