C++ 带有主体的纯虚函数的用例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2609299/
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
Use-cases of pure virtual functions with body?
提问by missingfaktor
I recently came to know that in C++ pure virtual functions can optionally have a body.
我最近才知道在 C++ 中,纯虚函数可以选择有一个函数体。
What are the real-world use cases for such functions?
这些功能的实际用例是什么?
采纳答案by sbi
The classic is a pure virtual destructor:
经典的是纯虚析构函数:
class abstract {
public:
virtual ~abstract() = 0;
};
abstract::~abstract() {}
You make it pure because there's nothing else to make so, and you want the class to be abstract, but you have to provide an implementation nevertheless, because the derived classes' destructors call yours explicitly. Yeah, I know, a pretty silly textbook example, but as such it's a classic. It must have been in the first edition of The C++ Programming Language.
你让它纯粹是因为没有别的东西可以做到这一点,并且你希望类是抽象的,但是你必须提供一个实现,因为派生类的析构函数显式调用你的析构函数。是的,我知道,这是一个非常愚蠢的教科书示例,但因此它是经典之作。它一定出现在The C++ Programming Language 的第一版中。
Anyway, I can't remember ever really needing the ability to implement a pure virtual function. To me it seems the only reason this feature is there is because it would have had to be explicitly disallowed and Stroustrup didn't see a reason for that.
无论如何,我不记得曾经真正需要实现纯虚函数的能力。对我来说,这个功能存在的唯一原因似乎是因为它必须被明确禁止,而 Stroustrup 没有看到这样做的原因。
If you ever feel you need this feature, you're probably on the wrong track with your design.
如果您觉得自己需要此功能,则您的设计可能走错了路。
回答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 Michael Burr
One reason that an abstract base class (with a pure virtual function) might provide an implementation for a pure virtual function it declares is to let derived classes have an easy 'default' they can choose to use. There isn't a whole lot of advantage to this over a normal virtual function that can be optionally overridden - in fact, the only real difference is that you're forcing the derived class to be explicit about using the 'default' base class implementation:
抽象基类(具有纯虚函数)可能为其声明的纯虚函数提供实现的一个原因是让派生类有一个简单的“默认”,它们可以选择使用。与可以选择覆盖的普通虚函数相比,这并没有太多优势 - 事实上,唯一真正的区别是您强制派生类明确使用“默认”基类实现:
class foo {
public:
virtual int interface();
};
int foo::interface()
{
printf( "default foo::interface() called\n");
return 0;
};
class pure_foo {
public:
virtual int interface() = 0;
};
int pure_foo::interface()
{
printf( "default pure_foo::interface() called\n");
return 42;
}
//------------------------------------
class foobar : public foo {
// no need to override to get default behavior
};
class foobar2 : public pure_foo {
public:
// need to be explicit about the override, even to get default behavior
virtual int interface();
};
int foobar2::interface()
{
// foobar is lazy; it'll just use pure_foo's default
return pure_foo::interface();
}
I'm not sure there's a whole lot of benefit - maybe in cases where a design started out with an abstract class, then over time found that a lot of the derived concrete classes were implementing the same behavior, so they decided to move that behavior into a base class implementation for the pure virtual function.
我不确定有很多好处 - 也许在设计开始时使用抽象类的情况下,随着时间的推移发现很多派生的具体类正在实现相同的行为,所以他们决定移动该行为到纯虚函数的基类实现中。
I suppose it might also be reasonable to put common behavior into the pure virtual function's base class implementation that the derived classes might be expected to modify/enhance/augment.
我认为将常见行为放入纯虚函数的基类实现中也可能是合理的,派生类可能需要修改/增强/增强。
回答by Ofek Shilon
The almighty Herb Sutter, former chair of the C++ standard committee, did give 3 scenarioswhere you might consider providing implementations for pure virtual methods.
全能的 Herb Sutter,C++ 标准委员会的前任主席,确实给出了 3 个你可以考虑为纯虚方法提供实现的场景。
Gotta say that personally – I find none of them convincing, and generally consider this to be one of C++'s semantic warts. It seems C++ goes out of its way to build and tear apart abstract-parent vtables, than exposes them briefly only during child construction/destruction, and thenthe community experts unanimously recommend never to use them.
不得不说个人 - 我发现它们都没有说服力,并且通常认为这是 C++ 的语义缺陷之一。似乎 C++ 不遗余力地构建和分解抽象父 vtables,而不是仅在 child 构造/销毁期间短暂地公开它们,然后社区专家一致建议永远不要使用它们。
回答by shoosh
One use case is calling the pure virtual function from the constructor or the destructor of the class.
一种用例是从类的构造函数或析构函数调用纯虚函数。
回答by Andrey
The only difference of virtual function with body and pure virtual function with body is that existence of second prevent instantiation. You can't mark class abstract in c++.
带体的虚函数和带体的纯虚函数的唯一区别是第二个防止实例化的存在。你不能在 C++ 中标记类抽象。
回答by Elvis Attro
This question can really be confusing when learning OOD and C++. Personally, one thing constantly coming in my head was something like: If I needed a Pure Virtual function to also have an implementation, so why making it "Pure" in first place ? Why not just leaving it only "Virtual" and have derived both benefit and override the base implementation ?
在学习 OOD 和 C++ 时,这个问题真的很容易让人困惑。就个人而言,我脑海中不断出现的一件事是:如果我需要一个纯虚拟函数来实现,那么为什么首先要让它成为“纯”?为什么不只保留它“虚拟”并获得好处并覆盖基本实现?
The confusion comes to the fact that many developers consider the no body/implementation as the primary goal/benefit of defining a pure virtual function. This is not true! The absence of body is in most cases a logical consequence of having a pure virtual function. The main benefit of having a pure virtual function is DEFINING A CONTRACT! By defining a pure virtual function, you want to FORCE every derived to ALWAYS provide their OWN IMPLEMENTATION of the function. This "CONTRACT aspect" is very important especially if you are developing something like a public API. Making the function only virtual is not so sufficient because derivatives are no longer forced to provide their own implementation, therefore you may loose the contract aspect (this can be limiting in the case of a public API). As commonly said : "Virtual functions CAN be overrided, Pure Virtual functions MUST be overrided." And in most cases, contracts are abstract concepts so it doesn't make sense for the corresponding pure virtual functions to have any implementation.
令人困惑的是,许多开发人员认为无主体/实现是定义纯虚函数的主要目标/好处。这不是真的!在大多数情况下,缺少 body 是拥有纯虚函数的逻辑结果。拥有纯虚函数的主要好处是定义合同!通过定义纯虚函数,您希望强制每个派生函数始终提供它们自己的函数实现。这个“合同方面”非常重要,特别是如果您正在开发诸如公共 API 之类的东西。仅将函数设为虚拟还不够,因为衍生工具不再被迫提供自己的实现,因此您可能会失去合约方面(这在公共 API 的情况下可能会受到限制)。正如人们常说的:“
But sometimes, and because life is weird, you may want to establish a strong contract among derivatives and also want them to somehow benefit from some default implementation while specifying their own behavior for the contract. Even if most book authors recommend to avoid getting yourself into these situations, the language needed to provide a safety net to prevent the worst! A simple virtual function wouldn't be enough since there might be risk of escaping the contract. So the solution C++ provided was to allow pure virtual functions to also be able to provide a default implementation.
但有时,因为生活很奇怪,你可能希望在衍生品之间建立一个强大的契约,并且还希望它们以某种方式从某些默认实现中受益,同时为契约指定自己的行为。即使大多数书籍作者建议避免让自己陷入这些情况,语言也需要提供一个安全网来防止最坏的情况发生!一个简单的虚函数是不够的,因为可能存在逃避合约的风险。所以 C++ 提供的解决方案是允许纯虚函数也能够提供默认实现。
The Sutter article cited above gives interesting use cases of having Pure Virtual functions with body.
上面引用的 Sutter 文章给出了具有纯虚函数和 body 的有趣用例。