【问题标题】:Should copy constructor be private or public复制构造函数应该是私有的还是公共的
【发布时间】:2012-03-14 02:25:49
【问题描述】:

我正在编写一个抽象类,它将成为其他几个类的父类。我认为应该将复制构造函数设为私有,因为您使用的是抽象类并且没有什么可复制的。但是,我不是 100% 确定。

我是否正确,如果我不正确,为什么要公开或保护它?

【问题讨论】:

    标签: c++ private copy-constructor public


    【解决方案1】:

    通过将复制构造函数设为私有,您将有助于防止意外的对象切片,即复制派生类但会丢失该派生类的所有属性。派生类可以创建自己的复制构造函数,这些构造函数是公共的并且可以做正确的事情。

    当抽象类有数据成员时,复制构造函数应该被保护而不是私有的一种情况。这并不经常发生。基类可以复制基类成员,而派生类复制自己的成员。

    class AbstractBase
    {
    public:
        AbstractBase(const std::string &init) : wtf(init) {}
        virtual ~AbstractBase() {}
        void DoSomething() = 0;
    protected:
        AbstractBase(const AbstractBase &r) : wtf(r.wtf) {}
    
        const std::string wtf;
    };
    
    class Derived : public AbstractBase
    {
    public:
        // ...
        Derived(const Derived &r) : AbstractBase(r), moredata(r.moredata) {}
    private:
        int moredata;
    };
    

    【讨论】:

    • 你是对的!我认为默认情况下会调用基类复制构造函数。显然你必须明确地调用它。大错特错!
    • 基类的抽象不会阻止切片吗?
    • @FredLarson,捂脸!当然你不能实例化一个抽象类。
    【解决方案2】:

    如果您不想复制类的对象,则复制构造函数应该是私有的。否则,它应该是公开的。

    【讨论】:

    • 基类构造函数不可能复制派生类,所以我不明白什么时候公开它才有意义。
    • @MarkRansom 我的意思是this,但人们仍然可以在派生类中实现复制构造函数。
    • 谢谢,我是这么认为的。一个后续问题,因为它是私有的并且永远不会被使用,所以复制构造函数中不需要任何代码,因为它永远不会被使用。对吗?
    • @Aaron 它不应该被使用,因此没有必要实现它。如果你尝试使用它,无论如何你都会得到一个编译错误。
    • @Aaron,如果复制构造函数中有代码,它会做什么?如果您的抽象基类具有数据成员,则可能必须对其进行初始化,在这种情况下,构造函数应该受到保护并由所有派生类复制构造函数调用。但通常情况并非如此。
    【解决方案3】:

    我认为protected 是最好的选择:它将决定对象是否可复制到派生类,同时禁止在抽象类级别复制,防止可怕的object slicing

    【讨论】:

    • 我认为在这种情况下,protected 和 private 之间的区别是没有实际意义的,因为基类复制构造函数将是空的,不需要调用。
    • @MarkRansom 我认为调用基类的复制构造函数是个好主意,即使您确定它当前是空的。只要基类中的复制构造函数保持为空,编译器就会对其进行优化,但如果有人重构基类以包含非空的复制构造函数,则派生类不需要更改。
    • 非常好。我已经编辑了自己的答案以包含这种可能性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    相关资源
    最近更新 更多