纯虚函数是抽象基类的必备属性。因此,不应该进行任何实现,这非常直观易懂。但最近我才知道纯虚函数仍然可以在以后定义并静态调用(而不是由对象实例调用)。我想不出这个原因。如果将一个虚函数定义为纯函数,那么实现它的原因是什么?
class A{
public:
...
virtual void interface() = 0; //Pure Virtual functions
...
}
void A::interface() //Implementation
{
cout<<"This the implementation for A interface";
}
我很好奇这背后的逻辑。为什么c ++的设计方式如此?
答案 0 :(得分:2)
有一个“默认”实现可能是有意义的,如果它对它们有用,具体类可以使用。他们仍然需要覆盖它,但可以非虚拟地调用基类版本:
struct B : A {
void interface() {
A::interface(); // call the default implementation
// and maybe do some B-specific things too
}
};
答案 1 :(得分:1)
我无法想出这个原因。如果将一个虚函数定义为纯函数,那么实现它的原因是什么?
纯虚函数的目的是不来禁止定义。它是将类标记为不可实现的。
提供定义对于派生类可能很有用:
struct A
{
virtual void foo() = 0;
};
void A::foo()
{
/* some common logic here */
}
struct B : A
{
virtual void foo() overrides
{
bar();
A::foo();
}
void bar();
};
struct C : A
{
virtual void foo() overrides
{
baz();
A::foo();
}
void baz();
};
答案 2 :(得分:1)
在这种情况下,你显然完全误解了“静态”一词的含义。
是的,纯虚函数仍然可以有实体,即它们仍然可以定义。
不,你不能在没有对象实例的情况下调用这样的函数,因为你似乎错误地相信了。具有正文的纯虚函数仍然是非静态成员函数。它仍然需要调用一个对象实例。
当有人说可以“静态”调用此类函数时,这意味着可以直接调用它,而不使用虚拟调度机制。通过虚拟调度的函数调用有时称为“虚拟调用”或“动态调用”,而直接函数调用有时称为“静态调用”。在此上下文中,术语“静态”假定具有完全不同的含义,不以任何方式与静态成员函数相关联。
在C ++语言中,可以通过在调用中指定合格的成员名称来显式执行直接的非虚拟(即“静态”)调用。例如,如果类B
派生自您的类A
,那么在某个方法B::foo()
中,您可以使用以下语法
void B::foo() {
A::interface(); // <- qualified method name
}
直接调用您提供的A::interface()
的实现。对于b
类型的对象B
,可以执行与
B b;
b.A::interface(); // <- qualified method name
在这两种情况下,都会针对特定对象执行调用(第一个示例中为*this
,第二个示例中为b
。
当派生类的析构函数调用基类的析构函数时,几乎同样的事情发生了,这就是为什么你经常会遇到纯虚拟析构函数的情况(即它们被声明为纯虚拟,但有一个体)。 / p>
答案 3 :(得分:1)
纯虚函数只是意味着函数必须被所有派生类覆盖,并不意味着函数不能/不应该有自己的实现。这种具有实现的纯虚函数的两个最明显的情况是:
virtual
,在这种情况下析构函数是最明显的选择,但在这样的析构函数中仍然需要一个实现。 答案 4 :(得分:1)
interface()= 0表示派生类必须提供实现,因此定义会影响派生类,但允许基类具有方法的实现,以便派生类始终可以调用基::接口()。