我刚刚发生了标题中的陈述.完整的报价是:
根据经验,使所有方法都是虚拟的(包括析构函数,而不是构造函数),以避免与遗漏虚拟关键字相关的问题.
我在Wrox的专业C++书中找到了这个.你可以谷歌检查.
有什么事吗?我原以为你只提供选择扩展点,而不是默认的可扩展性.例如,Herb Sutter在2001年发表的一篇文章就这么说了.从那时起,有什么改变发生了戏剧性的规范吗?(请注意,我是一名C++ noob,因此我在过去十年中没有关注过这个问题.)
考虑这些对象:
struct A
{
virtual void foo() = 0;
};
struct B
{
void foo() { /* neat implementation */ }
};
Run Code Online (Sandbox Code Playgroud)
我想知道为什么 - 编译器 - 明智 - 以下对象被认为是抽象的:
struct C : B, A
{
using B::foo; // I tried my best to make the compiler happy
};
Run Code Online (Sandbox Code Playgroud)
编译器不允许我这样做:
A* a = new C;
Run Code Online (Sandbox Code Playgroud)
Visual Studio 2010说:
'C':由于以下成员无法实例化抽象类:'void A :: foo(void)':是抽象的:请参阅'A :: foo'的声明
g ++ 4.6.3说:
无法分配抽象类型为"C"的对象,因为以下虚函数在'C'中是纯的:virtual void A :: foo()
我想这在C#中是允许的,但我不知道所涉及的机制主义 - 我只是好奇.
我的代码中有一个相对复杂的接口,并且希望将部分实现委托给另一个类,而不需要在实现中编写大量的转发函数.请参阅此简化示例代码:
#include <stdio.h>
struct Interface {
virtual void foo() = 0;
virtual void bar() = 0;
virtual ~Interface() {}
};
struct Delegate {
virtual void foo()
{ printf("foo\n"); }
};
struct Impl : public Interface, private Delegate {
// delegate foo to Delegate
using Delegate::foo;
void bar()
{ printf("bar\n"); }
};
int main() {
Interface* i = new Impl();
i->foo();
i->bar();
delete i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在G ++抱怨foo没有在Impl中实现.然而,在Impl中有一个完美的函数foo,它只是从另一个父类中获取.为什么编译器不能正确填写vtable?
(注意:我知道在这个特定的例子中,Delegate可以从Interface派生.我想了解是否可以委派功能而无需从接口派生委托.)