C++ 带实现的纯虚函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2089083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pure virtual function with implementation
提问by skydoor
My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.
我的基本理解是没有实现纯虚函数,但是,有人告诉我可能有纯虚函数的实现。
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
Is code above OK?
上面的代码可以吗?
What's the purpose to make it a pure virtual function with an implementation?
使其成为具有实现的纯虚函数的目的是什么?
回答by Michael Burr
A pure virtual
function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f()
in your example - if A::f()
were public
or protected
). Something like:
纯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();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
我能想到的用例是当存在或多或少合理的默认行为时,但类设计者希望仅显式调用这种默认行为。也可能是您希望派生类始终执行自己的工作,但也能够调用一组通用的功能。
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
请注意,尽管语言允许这样做,但我认为它并不是常用的东西(而且可以做到这一点的事实似乎让大多数 C++ 程序员,甚至是有经验的程序员感到惊讶)。
回答by Terry Mahaffey
To be clear, you are misunderstanding what = 0; after a virtual function means.
需要明确的是,您误解了什么 = 0;后一个虚函数的意思。
= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.
= 0 表示派生类必须提供实现,而不是基类不能提供实现。
In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.
实际上,当您将虚函数标记为纯 (=0) 时,提供定义的意义不大,因为除非有人通过 Base::Function(...) 显式调用它,否则它永远不会被调用,或者如果基类构造函数调用有问题的虚函数。
回答by JaredPar
The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.
它的优点是它强制派生类型仍然覆盖该方法,但还提供默认或附加实现。
回答by Kornel Kisielewicz
If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.
如果您有应该由派生类执行的代码,但您不希望直接执行它——并且希望强制覆盖它。
Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you mustprovide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.
您的代码是正确的,尽管总而言之这不是一个经常使用的功能,并且通常只在尝试定义纯虚拟析构函数时才能看到——在这种情况下,您必须提供一个实现。有趣的是,一旦您从该类派生,您就不需要覆盖析构函数。
Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.
因此,纯虚函数的一个明智用法是将纯虚析构函数指定为“非最终”关键字。
The following code is surprisingly correct:
以下代码出人意料地正确:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
回答by rmn
You'd have to give a body to a pure virtual destructor, for example :)
例如,您必须为纯虚拟析构函数提供一个主体:)
Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
阅读:http: //cplusplus.co.il/2009/08/22/pure-virtual-destructor/
回答by Brian R. Bondy
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
带或不带主体的纯虚函数仅仅意味着派生类型必须提供它们自己的实现。
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
如果您的派生类想要调用您的基类实现,则基类中的纯虚函数体非常有用。
回答by Yukiko
Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).
是的,这是正确的。在您的示例中,从 A 派生的类继承了接口 f() 和默认实现。但是你强制派生类实现 f() 方法(即使它只是调用 A 提供的默认实现)。
Scott Meyers discusses this in Effective C++ (2nd Edition)Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.
Scott Meyers 在Effective C++ (2nd Edition)Item #36 区分接口继承和实现继承中对此进行了讨论。项目编号在最新版本中可能已更改。
回答by Nir Hedvat
The 'virtual void foo() =0;' syntax does not mean you can't implement foo() in current class, you can. It also does not mean you must implement it in derived classes. Before you slap me, let's observe the Diamond Problem: (Implicit code, mind you).
'虚拟 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;
}
Now, the obj->foo() invocation will result in B::foo() and then C::bar().
现在,obj->foo() 调用将导致 B::foo() 和 C::bar()。
You see... pure virtual methods do not have to be implemented in derived classes (foo() has no implementation in class C - compiler will compile) In C++ there are a lot of loopholes.
你看……纯虚方法不必在派生类中实现(foo() 在类 C 中没有实现 - 编译器会编译)在 C++ 中有很多漏洞。
Hope I could help :-)
希望我能帮上忙:-)
回答by Gupta
One important use-case of having a pure virtual method with an implementation body, is when you want to have an abstract class, but you do not have any proper methods in the class to make it pure virtual. In this case, you can make the destructor of the class pure virtual and put your desired implementation (even an empty body) for that. As an example:
使用带有实现体的纯虚方法的一个重要用例是,当您想要一个抽象类,但类中没有任何适当的方法使其成为纯虚方法时。在这种情况下,您可以使类的析构函数纯虚拟,并为此放置所需的实现(甚至是空体)。举个例子:
class Foo
{
virtual ~Foo() = 0;
void bar1() {}
void bar2(int x) {}
// other methods
};
Foo::~Foo()
{
}
This technique, makes the Foo
class abstract and as a result impossible to instantiate the class directly. At the same time you have not added an additional pure virtual method to make the Foo
class abstract.
这种技术使Foo
类抽象,因此无法直接实例化类。同时您还没有添加额外的纯虚方法来使Foo
类抽象。