簡體   English   中英

如何確定c ++類是否可復制

[英]How to determine whether a c++ class is copyable

我有興趣提高我對如何避免編寫導致復制時出現問題的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>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時是否有任何可能導致問題的事情? 我的期望是復制將創造一個完美的物有所值的副本。

問我問題的一般方法如下: 一般來說,復制課時哪些類型的東西可能會導致問題? 除了“三條規則”(或“五條規則”)之外還有什么可以關注何時復制課程?

嗯,這個問題很容易引起誤解。

一個班輪答案可能是 - 使用std :: is_copy_constructible來查明是否可以復制一個類。

如果一個類具有已刪除或私有的復制構造函數/賦值運算符,或者至少有一個成員具有已刪除或私有的復制構造函數/賦值運算符(以遞歸方式應用),則該類是不可復制的。

例:

#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

同樣適用於不可移動..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM