我不是复制结构的粉丝。太多次了,我写了
void MyFunc(MyClass val)
而不是
void MyFunc(const MyClass& val)
并且不得不花费数小时调试已经在传递值克隆的析构函数中删除的指针的bug,或者发现减速因为我每次调用MyFunc时都会复制MyClass的每个成员。
所以我不想允许复制构造函数。
我知道你可以用每个班级来禁止他们
private:
MyClass(const MyClass&)
但我不想在每个班级都这样做。
是否有编译器开关默认关闭复制构造?有没有理由我应该允许除内置类型和指针之外的任何内容的复制构造? (这些相同的问题也适用于复制作业)
答案 0 :(得分:10)
是否有编译器开关默认关闭复制构造?
不,我真的希望没有。幸运的是,据我所知,情况确实如此。
我是否应该允许在内置类型和指针以外的任何内容上进行复制?
<强>不确定即可。例如,为您的类型提供值语义,并将您的类的不同实例视为同一个概念实体。在这种情况下,创建副本变得非常方便。
如果你想要一个不可复制的类,另一方面(有用例),你可以将复制构造函数声明为private
(如你自己建议的那样),或者在C语言中++ 11,将其标记为已删除:
struct X
{
X(X const&) = delete;
};
关于你所写的内容:
太多次,我写了
void MyFunc(MyClass val)
而不是void MyFunc(const MyClass& val)
并且不得不花费数小时调试错误
我知道你可能犯错误,但你必须向他们学习。您还可以编写一个普通函数,例如下面的foo()
:
void foo(int x) { x++; }
并且发誓数小时试图找出原因,当您将其作为参数传递给值为3
的变量时,调用返回后该变量的值不是4
。哦,你忘了添加参考符号:
void foo(int& x) { x++; }
// ^
现在这是一个需要编译器选项的原因,它会使默认值为pass-by-reference吗?并不是的。这将是改变语言规则的一种选择。
想象一下,如果你的编译器确实有你想要的这样一个开关会发生,有一天你会把你的程序发送给没有使用那个开关的其他人:他们多少小时花在调试上以找出问题所在?
我的建议是从经验中学习,并尝试使您的阅读和写作技能适应标准语言,而不是相反。
答案 1 :(得分:1)
没有神奇的开关。你只是犯了编程错误,希望语言改变。如果在堆上分配内存,则必须(或至少应)覆盖默认的复制构造函数并处理该动态内存。或者你可以使用一些现成的类,比如std :: vector或std::auto_ptr
({+ 1}}在C ++ 11中。)
答案 2 :(得分:-1)
我所做的是在课堂上声明副本ctor,但从不在任何地方定义它。如果我编写使用copy ctor的代码,那么我会从链接器中获得一个未定义的符号。