提问人:Nico Schlömer 提问时间:1/2/2017 最后编辑:Nico Schlömer 更新时间:1/3/2017 访问量:1147
零规则与基类析构函数
rule of zero vs. base class destructors
问:
我有一个基类和一个派生类,我希望编译器为我自动生成移动构造函数和移动赋值运算符。遵循零法则,我将所有内存管理留给编译器,只使用 2 级类(没有原始指针、数组等):Base
D
#include <iostream>
class Base{
public:
Base(): a_(42) {}
virtual void show() { std::cout << "Base " << a_ << std::endl; }
private:
int a_;
};
class D : Base {
public:
D(): b_(666) {}
void show() { std::cout << "D " << b_ << std::endl; }
private:
int b_;
};
int main() {
Base b;
b.show();
D d;
d.show();
return 0;
}
应该就是这样,对吧?
输入 C++ 核心准则:
基类析构函数应为公共和虚拟,或受保护和非虚拟。
啊,所以我想我必须添加一个析构函数。但这将取消自动生成的移动函数!Base
这里的清洁方法是什么?
答:
8赞
AMA
1/2/2017
#1
您可以编译器生成的所有内容。
请参阅(底部):http://en.cppreference.com/w/cpp/language/rule_of_three= default
在您的案例中,它可能看起来像这样:
class Base{
public:
Base(): a_(42) {}
Base(const Base&) = default;
Base(Base&&) = default;
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = default;
virtual ~Base() = default;
virtual void show() { std::cout << "Base " << a_ << std::endl; }
private:
int a_;
};
2赞
Jarod42
1/2/2017
#2
您可以创建一次类,例如
struct VirtualBase
{
virtual ~VirtualBase() = default;
VirtualBase() = default;
VirtualBase(const VirtualBase&) = default;
VirtualBase(VirtualBase&&) = default;
VirtualBase& operator = (const VirtualBase&) = default;
VirtualBase& operator = (VirtualBase&&) = default;
};
然后遵循零法则:
class Base : VirtualBase
{
public:
Base(): a_(42) {}
virtual void show() { std::cout << "Base " << a_ << std::endl; }
private:
int a_;
};
评论
0赞
iammilind
1/2/2017
很好的建议,我正要写这个答案。但不确定,当涉及多重继承时,它的命运会是什么。虚拟继承不是安全吗?VirtualBase
0赞
Jarod42
1/2/2017
@iammilind:虚拟继承比简单继承成本高,所以除非需要,否则我会坚持正常继承。
0赞
n. m. could be an AI
1/2/2017
@iammilind虚拟继承或不继承都是安全的。
评论
= default