【发布时间】:2015-08-25 03:52:46
【问题描述】:
我是一名 Java 程序员,对为纯虚拟函数提供定义这一事实感到困惑。在 Java 中,我习惯于将抽象方法视为我们将在基类中提供定义的方法。但是下面的代码是完全有效的:
#include <iostream>
struct A
{
virtual ~A() = 0;
};
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
};
A *a = new B;
int main()
{
delete a;
}
但是如果我们尝试做这样的事情:
#include <iostream>
struct A
{
virtual ~A() = 0;
virtual void foo() = 0;
};
void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
};
A *a = new B;
int main()
{
delete a;
}
编译器会抱怨没有为纯虚函数提供定义。为什么我们可以在命名空间范围内定义纯虚析构函数,而对于普通的成员函数却不能这样做。
这是一个例外而不是一个规则?
【问题讨论】:
-
什么?为纯虚函数提供定义是完全合法的。编译器永远不会抱怨这一点。第二个代码的唯一问题是您试图实例化抽象类
B,而不是为纯函数提供定义。 -
@AnT 但我是在命名空间范围内完成的。我提供了这个定义,有什么问题?
-
在哪里?我在任何地方都没有看到
B::foo的定义。A::foo是一个纯虚函数。除非你用B::foo覆盖它,否则它在B中也将保持纯净。