如何确定c ++类是否可复制

时间:2013-06-07 23:32:37

标签: c++ class noncopyable

我有兴趣提高对如何避免编写导致复制时出现问题的C ++类的理解。

特别是,我编写了一个名为Policy的类,我打算复制它。我有定义了非默认的析构函数,复制构造函数或复制赋值运算符。我重载的唯一操作符如下:

friend bool operator== (const Policy& p1, const Policy& p2) {
    for(int i=0; i<p1.x.size(); i++) {
        if(p1.x[i] != p2.x[i])
            return false;
    }
    return true;
}

班级的成员要么是标准数据类型,例如intdoubleboolstd::stringstd::vector<double>std::vector<int>,{ {1}},或者我定义的几个小的(因而不是过于复杂的)类中的一个,它们绝对可以复制而没有任何问题。现在,有std::vector<string>的成员是Policy类的实例,它是我作为不可复制的第三方数据类型的包装器构建的类; NRRan如下:

NRRan

class NRRan { public: double doub() { return stream->doub(); } int intInterval(const int& LB, const int& UB) { return LB+int64()%(UB-LB+1); } void setNewSeed(const long& seed) { delete stream; stream = new Ranq1(seed); } NRRan() { stream = new Ranq1(12345); } ~NRRan() { delete stream; } NRRan(const NRRan& nrran) { stream = new Ranq1(12345); *stream = *(nrran.stream); } NRRan& operator= (const NRRan& nrran) { if(this == &nrran) return *this; delete stream; stream = new Ranq1(12345); *stream = *(nrran.stream); return *this; } private: Ranq1* stream; // underlying C-struct Ullong int64() { return stream->int64(); } }; 类的重点是使NRRan可复制。所以,考虑到我所描述的Ranq1类(抱歉,我无法发布大部分代码),在复制Policy时是否有任何可能导致问题的问题?我的期望是复制将创造一个完美的物有所值的副本。

提出问题的一般方法如下:一般来说,复制课程时哪些类型的事情可能会导致问题?除了“三个规则”之外还有什么吗? (或“五条规则”)在关注课堂时是否可以复制?

2 个答案:

答案 0 :(得分:2)

嗯,这个问题有误导性。

单行答案可以是 - 使用std::is_copy_constructible来查明是否可以复制课程。

答案 1 :(得分:0)

如果类具有已删除或私有副本构造函数/赋值运算符,或者至少有一个具有已删除或私有副本构造函数/赋值运算符的成员(递归应用),则该类不可复制。

示例:

#include <iostream>
#include <type_traits>

class A{

};

class B {
private:
    A a;
    B(const B&) = default;
    B& operator=(const B&) = default;
public:
    B() = default;
};

class NonCopyable {
    int i_;
public:
    NonCopyable() : i_{0}
    {}
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};


struct Composable {
    NonCopyable nc;
};

struct C {
    A a;
    B b;
};


int main()
{
    A a;
    A aa{a};                // copy construct
    A aaa = a;              // copy assign
    B b;
    //B bb{b};              // can't
    //B bbb = b;                // can't 
    NonCopyable nc;
    //NonCopyable nc2 = nc; // cannot
    //NonCopyable nc3{nc};  // cannot
    Composable comp;
    //Composable comp2{comp};   // can't copy construct either
    //Composable comp3 = comp;// can't copy assign either

    std::cout << std::boolalpha;
    std::cout << std::is_copy_assignable_v<A> << '\n';
    std::cout << std::is_copy_assignable_v<NonCopyable> << '\n';
    std::cout << std::is_copy_constructible_v<Composable> << '\n';
    std::cout << std::is_copy_constructible<C>::value << '\n';
}

输出

true
false
false
false

类似于不可移动。