c ++ - 带实现的纯虚函数
我的基本理解是没有纯虚函数的实现,但是,有人告诉我可能有纯虚函数的实现。
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<
}
代码是否正常?
使其成为具有实现的纯虚函数的目的是什么?
skydoor asked 2019-05-12T18:38:14Z
8个解决方案
181 votes
纯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 ++程序员,甚至是经验丰富的程序员都感到惊讶)。
Michael Burr answered 2019-05-12T18:38:43Z
64 votes
要清楚,你误解了什么= 0; 在虚函数意味着之后。
= 0表示派生类必须提供实现,而不是基类不能提供实现。
在实践中,细心的鞋垫将虚函数标记为纯(= 0)时,提供定义几乎没有意义,因为除非有人通过Base :: Function(...)明确地这样做,否则永远不会调用它。 基类构造函数调用有问题的虚函数。
Terry Mahaffey answered 2019-05-12T18:39:22Z
20 votes
它的优点是它强制派生类型仍然覆盖方法,但也提供默认或附加实现。
JaredPar answered 2019-05-12T18:39:47Z
16 votes
如果你有代码应该由派生类执行,但你不希望它直接执行 - 并且你想强制它被覆盖。
您的代码是正确的,尽管所有这些都不是常用的功能,并且通常仅在尝试定义纯虚拟析构函数时才会出现 - 在这种情况下,您必须提供实现。 有趣的是,一旦你从该类派生,你不需要覆盖析构函数。
因此,纯虚函数的一个合理用法是将纯虚析构函数指定为“非最终”关键字。
以下代码非常正确:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
Kornel Kisielewicz answered 2019-05-12T18:40:34Z
5 votes
你必须给一个纯虚拟析构函数的主体,例如:)
阅读:[http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/]
(链接损坏,使用存档)
rmn answered 2019-05-12T18:41:18Z
4 votes
是的,这是正确的。 在您的示例中,从A派生的类继承了接口f()和默认实现。 但是你强制派生类来实现方法f()(即使它只是调用A提供的默认实现)。
Scott Meyers在Effective C ++(第2版)第36项中讨论了这一点。区分接口的继承和实现的继承。 最新版本中的项目编号可能已更改。
Yukiko answered 2019-05-12T18:41:50Z
4 votes
带或不带主体的纯虚函数只是意味着派生类型必须提供自己的实现。
如果派生类要调用基类实现,则基类中的纯虚函数体很有用。
Brian R. Bondy answered 2019-05-12T18:42:22Z
1 votes
'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-&gt; foo()调用将导致B :: foo(),然后是C :: bar()。
你看......纯虚方法不必在派生类中实现(foo()在C类中没有实现 - 编译器会编译)在C ++中存在很多漏洞。
希望我能帮忙:-)
Nir Hedvat answered 2019-05-12T18:43:08Z