c++ - 三/五规则是否适用于继承和虚拟析构函数?

标签 c++ c++11

假设我们有一个非常基本的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/

相关文章:

C++类名冲突

c++ - 如何测试阻塞与异步?

c++ - 将字符串拆分为 2 个 vector 。将字符串转换为浮点类型时遇到问题

C++ 互斥体和 const 正确性

c++ - 多线程计算mean和std并不能提高效率

c++ - 命名空间与包含的类同名,gcc 可以,clang 不行

c++ - 如果子级覆盖另一个具有相同名称和不同签名的方法,则不会继承基类方法

c++ - 如何制作一个采用 2 个参数而不是 1 个参数的递归 lambda 函数?

c++ - 指向虚拟成员函数的指针。它是如何工作的?

java - 如何为多个程序共享变量?