synaptik
synaptik

Reputation: 9519

How to determine whether a c++ class is copyable

I'm interested in improving my understanding of how to avoid writing a C++ class that causes problems when copied.

In particular, I've written a class named Policy that I intend to copy. I have not defined a non-default destructor, copy constructor, or copy assignment operator. The only operator I've overloaded is the following:

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;
}

The class's members are either standard data types such as int, double, bool, std::string, std::vector<double>, std::vector<int>, std::vector<string>, or one of a few small (and thus not overly complex) classes I defined that are definitely copyable without any problem. Now, there is a member of Policy that is an instance of the NRRan class, which is a class I built as a wrapper around a non-copyable third-party data type; NRRan is as follows:

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(); }    
};

But the whole point of the NRRan class is to make Ranq1 copyable. So, given the Policy class as I've described it (sorry, I am unable to post a large part of the code), is there any thing that might cause a problem when I copy Policy? My expectation is that copying will create a perfect value-for-value copy.

A more general way of asking my question is the following: Generally speaking, what types of things can possibly cause problems when copying a class? Is there anything in addition to the "Rule of Three" (or "Rule of Five") to be concerned about when making a class copyable?

Upvotes: 3

Views: 6534

Answers (2)

KeyC0de
KeyC0de

Reputation: 5267

A class is non-copyable if it has a deleted or private copy constructor/assignment operator, or has at least one member with deleted or private copy constructor/assignment operator (applies recursively).

example:

#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';
}

Output

true
false
false
false

Similarly for non-movable..

Upvotes: 0

g-217
g-217

Reputation: 2210

Well, this question is misleading..

One liner answer can be like -- use std::is_copy_constructible to find out if a class can be copied or not.

Upvotes: 2

Related Questions