使用在派生 类 中声明为纯虚拟的方法
using a method declared pure virtual in derived classes
我正在处理一段代码,我看到了一些奇怪的东西,一个 class "MyClass" 的方法我们称之为 X() :
virtual void X() = 0;
所以 MyClass 是一个抽象 class 并且在 MyClass.cpp 中 X() 有一个正确的实现...
在 MyClass 的派生 classes 中,此方法通过 MyClass::X();
调用
我认为 = 0
会使它的实现无效...但事实并非如此,事实上,它在派生的 classes 中可用。
请问编译器在遇到= 0
时到底做了什么?
来自标准(9.2 Class成员[class.mem]):
= 0
is the pure-specifier
它告诉编译器:
- class是抽象
- 方法将在class定义之外定义
(通常在派生中class)
示例 1(构建失败)
如果我没有正确理解你的问题,那么你的问题是这样的:
class MyClass {
public:
virtual void X() = 0;
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyDerivedClass::X() { MyClass::X(); }
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
如果是这样,构建应该会失败:
错误:
undefined reference to 'MyClass::X()'
示例2(构建成功)
但是,即使方法 MyClass::X()
声明为 纯虚拟,
你可以提供一个定义。以下将起作用。 class MyClass
仍然是抽象,但是你可以调用方法MyClass::X()
.
#include <iostream>
class MyClass {
public:
virtual void X() = 0; // pure virtual method
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyClass::X() { // pure virtual method definition
std::cout << "MyClass::X()" << std::endl;
}
void MyDerivedClass::X() {
MyClass::X();
std::cout << "MyDerivedClass::X()" << std::endl;
}
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
输出:
MyClass::X()
MyDerivedClass::X()
您无法使用纯虚方法创建 class 的实例,但在某些情况下您可以调用纯虚方法,它将是一个 error
我认为编译器会为纯虚方法创建一个带有 NULL 指针的 vtable。
=0 告诉编译器两件事:
- 不需要常规的 out-of-class 函数定义(尽管允许)。如果没有这样的定义,并且实际调用了该函数,则为runtine错误。
- class 是抽象的,无法实例化,无论第 1 点的定义是否存在。尝试这样做应该被标记为编译时错误。不覆盖函数的派生 classes 也是抽象的。
我正在处理一段代码,我看到了一些奇怪的东西,一个 class "MyClass" 的方法我们称之为 X() :
virtual void X() = 0;
所以 MyClass 是一个抽象 class 并且在 MyClass.cpp 中 X() 有一个正确的实现... 在 MyClass 的派生 classes 中,此方法通过 MyClass::X();
调用我认为 = 0
会使它的实现无效...但事实并非如此,事实上,它在派生的 classes 中可用。
请问编译器在遇到= 0
时到底做了什么?
来自标准(9.2 Class成员[class.mem]):
= 0
is thepure-specifier
它告诉编译器:
- class是抽象
- 方法将在class定义之外定义 (通常在派生中class)
示例 1(构建失败)
如果我没有正确理解你的问题,那么你的问题是这样的:
class MyClass {
public:
virtual void X() = 0;
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyDerivedClass::X() { MyClass::X(); }
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
如果是这样,构建应该会失败:
错误:
undefined reference to 'MyClass::X()'
示例2(构建成功)
但是,即使方法 MyClass::X()
声明为 纯虚拟,
你可以提供一个定义。以下将起作用。 class MyClass
仍然是抽象,但是你可以调用方法MyClass::X()
.
#include <iostream>
class MyClass {
public:
virtual void X() = 0; // pure virtual method
};
class MyDerivedClass : MyClass {
public:
virtual void X();
};
void MyClass::X() { // pure virtual method definition
std::cout << "MyClass::X()" << std::endl;
}
void MyDerivedClass::X() {
MyClass::X();
std::cout << "MyDerivedClass::X()" << std::endl;
}
int main()
{
MyDerivedClass mdc;
mdc.X();
return 0;
}
输出:
MyClass::X()
MyDerivedClass::X()
您无法使用纯虚方法创建 class 的实例,但在某些情况下您可以调用纯虚方法,它将是一个 error
我认为编译器会为纯虚方法创建一个带有 NULL 指针的 vtable。
=0 告诉编译器两件事:
- 不需要常规的 out-of-class 函数定义(尽管允许)。如果没有这样的定义,并且实际调用了该函数,则为runtine错误。
- class 是抽象的,无法实例化,无论第 1 点的定义是否存在。尝试这样做应该被标记为编译时错误。不覆盖函数的派生 classes 也是抽象的。