c++ - 默认可复制派生类

标签 c++

假设我有一个愚蠢的类层次结构。

class Base {
public:
    Base() = default;
    virtual ~Base() = default;
    virtual void print() = 0;
};

class Derived : public Base {
public:
    Derived() {
        stuff.resize(1000);
    }
    void print() override {
        cout << "Whatever\n";
    }
private:
    std::vector<int> stuff;
};

我想像这样使用它:

void printIt(Base* b) {
    b->print();
}

int main() {

    Derived d1;
    Derived d2 = d1;

    printIt(&d1);
    printIt(&d2);
}

这编译并工作正常,但 Clang 警告我:

warning: definition of implicit copy constructor for 'Base' is deprecated because it has a user-declared destructor

这看起来不错而且正确 - 如果人们复制 Base 就会发生坏事,所以我将删除复制构造函数。

class Base {
public:
    Base() = default;
    virtual ~Base() = default;
    virtual void print() = 0;

    Base(const Base&) = delete;
    Base& operator=(const Base&) = delete;
};

但是我得到这个错误:

main.cpp:38:17: error: call to implicitly-deleted copy constructor of 'Derived'
        Derived d2 = d1;
                ^    ~~
main.cpp:18:21: note: copy constructor of 'Derived' is implicitly deleted because base class 'Base' has a deleted copy
      constructor
    class Derived : public Base {
                    ^
main.cpp:14:9: note: 'Base' has been explicitly marked deleted here
        Base(const Base&) = delete;
        ^

好吧...很公平。如果我尝试将其显式添加回来怎么办?

class Derived : public Base {
public:
    Derived() {
        stuff.resize(1000);
    }
    void print() override {
        cout << "Whatever\n";
    }

    Derived(const Derived&) = default;

private:
    std::vector<int> stuff;
};

然后:

main.cpp:40:17: error: call to implicitly-deleted copy constructor of 'Derived'
        Derived d2 = d1;
                ^    ~~
main.cpp:27:9: note: explicitly defaulted function was implicitly deleted here
        Derived(const Derived&) = default;
        ^
main.cpp:18:21: note: copy constructor of 'Derived' is implicitly deleted because base class 'Base' has a deleted copy
      constructor
    class Derived : public Base {
                    ^
main.cpp:14:9: note: 'Base' has been explicitly marked deleted here
        Base(const Base&) = delete;
        ^

没有喜悦,这也有点道理。这里的解决方案是什么?我应该忽略原来的警告吗?也许我应该将 Base(Base&) 等添加为 protected

最佳答案

因此,如果我将复制/赋值设置为 protected,它会在没有警告的情况下进行编译。这似乎是一个合理的解决方案:

class Base {
public:
    Base() = default;
    virtual ~Base() = default;
    virtual void print() = 0;

protected:        
    Base(const Base&) = default;
    Base& operator=(const Base&) = default;
};

class Derived : public Base {
public:
    Derived() {
        stuff.resize(1000);
    }
    void print() override {
        cout << "Whatever\n";
    }

private:
    std::vector<int> stuff;
};

void printIt(Base* b) {
    b->print();
}

int main() {

    Derived d1;
    Derived d2 = d1;

    printIt(&d1);
    printIt(&d2);
}

关于c++ - 默认可复制派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48094040/

相关文章:

c++ - 如何避免 C++ 中的多重定义?

c++ - 在 Arduino 上从字符串中提取整数

c++ - 在嵌入式系统上从 DOS 切换到 Linux

c++ - 如何执行此 DirectFB 示例?

c++ - 动态绑定(bind)子类函数

c# - 通过 NVIDIA 驱动程序以编程方式设置显示器亮度

c++ - QFileDialog 如何将文件名设置为文本字段并单独使用 QFileDialog 和几个文本字段

c++ - 枚举 HWND 属性 C++

c++ - 将元类级别添加到 C++ 对象模型

没有宏的 C++ 简单反射 : Print Variable Name and Its Value