假设我们有一个非常基本的class A
:
class A {
public:
void SetName(const std::string& newName) {
m_name=newName;
}
void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
private:
std::string m_name;
};
我们想用 class B
扩展这个类,所以我们添加我们的虚拟析构函数,将成员更改为 virtual
并将 private
更改为 保护
为inh:
class A {
public:
virtual ~A() {}
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
class B : public A {
public:
virtual void Print() const {
std::printf("B::Print(). Name: %s\n",m_name.c_str());
}
};
既然我们在 class A
中添加了析构函数,我们是否需要像这样创建一个复制构造函数和复制运算符?
class A {
public:
virtual ~A() {}
A() = default;
A(const A& copyFrom){
*this = copyFrom;
}
virtual A& operator=(const A& copyFrom){
m_name=copyFrom.m_name;
return *this;
};
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
对我来说这似乎没有必要,因为默认的复制运算符和复制构造函数会做同样的事情。
最佳答案
要为该语言的潜在未来发展做好准备,您确实应该在添加虚拟析构函数时显式默认复制/移动构造函数和赋值运算符。这是因为当类具有用户声明的析构函数时,C++11、12.8/7 不推荐隐式生成复制构造函数。
幸运的是,C++11 的显式默认使它们的定义变得容易:
class A {
public:
virtual ~A() {}
A() = default;
A(const A& copyFrom) = default;
A& operator=(const A& copyFrom) = default;
A(A &&) = default;
A& operator=(A &&) = default;
void SetName(const std::string& newName) {
m_name=newName;
}
virtual void Print() const {
std::printf("A::Print(). Name: %s\n",m_name.c_str());
}
protected:
std::string m_name;
};
关于c++ - 三/五规则是否适用于继承和虚拟析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26039907/