2

我有兴趣提高我对如何避免编写复制时导致问题的 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;
}

该类的成员要么是标准数据类型,例如int, double, bool, std::string, std::vector<double>, std::vector<int>, 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我所描述的课程(对不起,我无法发布大部分代码),当我复制时是否有任何可能导致问题的事情Policy?我的期望是复制将创造出完美的价值复制。

一个更一般的问我问题的方法如下:一般来说,在复制一个类时,哪些类型的东西可能会导致问题? 在使课程可复制时,除了“三法则”(或“五法则”)之外,还有什么需要注意的吗?

4

2 回答 2

1

嗯,这个问题是误导..

一个线性答案可以是——使用std::is_copy_constructible来确定一个类是否可以被复制。

于 2015-09-04T14:26:34.743 回答
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

同样对于非移动..

于 2018-10-03T13:07:26.020 回答