零规则与基础 class 析构函数
rule of zero vs. base class destructors
我有一个基础 class Base
和一个派生的 class D
,我希望移动构造函数和移动赋值运算符由编译器对我来说。在 Rule of Zero 之后,我将所有内存管理留给编译器,只使用 level-2 classes(没有原始指针、数组等):
#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;
}
应该是这样吧?
A base class destructor should be either public and virtual, or protected and nonvirtual.
啊,所以我想我必须向 Base
添加一个析构函数。但这将取消自动生成的移动功能!
这里干净的出路是什么?
您可以 = default
您希望编译器生成的所有内容。
见(底部):http://en.cppreference.com/w/cpp/language/rule_of_three
在您的情况下,它可能类似于:
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_;
};
您可以创建一次 class 赞
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_;
};
我有一个基础 class Base
和一个派生的 class D
,我希望移动构造函数和移动赋值运算符由编译器对我来说。在 Rule of Zero 之后,我将所有内存管理留给编译器,只使用 level-2 classes(没有原始指针、数组等):
#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;
}
应该是这样吧?
A base class destructor should be either public and virtual, or protected and nonvirtual.
啊,所以我想我必须向 Base
添加一个析构函数。但这将取消自动生成的移动功能!
这里干净的出路是什么?
您可以 = default
您希望编译器生成的所有内容。
见(底部):http://en.cppreference.com/w/cpp/language/rule_of_three
在您的情况下,它可能类似于:
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_;
};
您可以创建一次 class 赞
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_;
};