C++ 中的虚拟析构函数与普通方法
virtual destrutors vs normal methods in C++
考虑以下三个 C++ 程序:
节目 1
struct base{
virtual ~base() =0;
};
struct derived: public base{
~derived();
};
derived::~derived(){}
int main(){}
节目 2
struct base{
virtual ~base() =0;
};
struct derived: public base{
~derived(){}
};
int main(){}
节目 3
struct base{
virtual void func() =0;
};
struct derived: public base{
void func();
};
void derived::func(){}
int main(){}
程序 #2 和 #3 编译并且 运行 很好,但是第一个给出以下错误:
Undefined symbols for architecture x86_64:
"base::~base()", referenced from:
derived::~derived() in main-d923b9.o
ls: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我想知道为什么我无法在 class 定义之外定义虚拟析构函数,但我可以在 class 定义内定义。此外,我可以在 class 之外定义方法,但不能定义析构函数。
这是错误的
struct base{
virtual ~base() =0;
};
因为base::~base
没有定义。即使它已被声明为纯虚函数,也需要对其进行定义(在 class 之外,没有语法方法可以将函数声明为纯虚函数并将其内联定义)因此 derived
可以从中继承:
struct base
{
virtual ~base() = 0;
};
base::~base() {}
I'd like to know why I am unable to define virtual destructors outside of the class definition
嗯,你可以:我刚刚做到了。
那么,为什么你需要实现一个已经被声明为纯虚拟的函数(~base
)?
由于derived
继承自base
,当derived
类型的对象被析构时,它必然会调用base
的析构函数。这就是继承的工作方式。从某种意义上说,derived::~derived
需要 link 和 base::~base
。尽管 base::~base
是一个纯虚拟(意味着从 base
继承的 class 不是完整类型,除非它定义了析构函数)它 需要 被定义以便 ~derived
找到它并且 link 他们变得快乐。
为什么要构建程序 2,答案在于 link 的工作原理。当函数定义在 class 声明之外时,linker 需要在最终的二进制文件中创建函数体,因此它也需要有 ~base() 定义。
如果你在主体中放入案例 2 derived d;
,你将得到与案例 1 相同的错误,因为 linker 将必须创建派生成员函数定义并将需要 ~base() 主体,如案例 1.
考虑以下三个 C++ 程序:
节目 1
struct base{
virtual ~base() =0;
};
struct derived: public base{
~derived();
};
derived::~derived(){}
int main(){}
节目 2
struct base{
virtual ~base() =0;
};
struct derived: public base{
~derived(){}
};
int main(){}
节目 3
struct base{
virtual void func() =0;
};
struct derived: public base{
void func();
};
void derived::func(){}
int main(){}
程序 #2 和 #3 编译并且 运行 很好,但是第一个给出以下错误:
Undefined symbols for architecture x86_64: "base::~base()", referenced from: derived::~derived() in main-d923b9.o ls: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
我想知道为什么我无法在 class 定义之外定义虚拟析构函数,但我可以在 class 定义内定义。此外,我可以在 class 之外定义方法,但不能定义析构函数。
这是错误的
struct base{
virtual ~base() =0;
};
因为base::~base
没有定义。即使它已被声明为纯虚函数,也需要对其进行定义(在 class 之外,没有语法方法可以将函数声明为纯虚函数并将其内联定义)因此 derived
可以从中继承:
struct base
{
virtual ~base() = 0;
};
base::~base() {}
I'd like to know why I am unable to define virtual destructors outside of the class definition
嗯,你可以:我刚刚做到了。
那么,为什么你需要实现一个已经被声明为纯虚拟的函数(~base
)?
由于derived
继承自base
,当derived
类型的对象被析构时,它必然会调用base
的析构函数。这就是继承的工作方式。从某种意义上说,derived::~derived
需要 link 和 base::~base
。尽管 base::~base
是一个纯虚拟(意味着从 base
继承的 class 不是完整类型,除非它定义了析构函数)它 需要 被定义以便 ~derived
找到它并且 link 他们变得快乐。
为什么要构建程序 2,答案在于 link 的工作原理。当函数定义在 class 声明之外时,linker 需要在最终的二进制文件中创建函数体,因此它也需要有 ~base() 定义。
如果你在主体中放入案例 2 derived d;
,你将得到与案例 1 相同的错误,因为 linker 将必须创建派生成员函数定义并将需要 ~base() 主体,如案例 1.