我有兴趣提高对如何避免编写导致复制时出现问题的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>
,{ {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
时是否有任何可能导致问题的问题?我的期望是复制将创造一个完美的物有所值的副本。
提出问题的一般方法如下:一般来说,复制课程时哪些类型的事情可能会导致问题?除了“三个规则”之外还有什么吗? (或“五条规则”)在关注课堂时是否可以复制?
答案 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
类似于不可移动。