例如这是正确的:
class C
{
private:
C();
C(const & C other);
}
或者您应该提供定义:
class C
{
private:
C() {};
C(const & C other) {};
}
? 谢谢你目前的答案。让我们扩展这个问题 - 编译器是否在其中一个示例中生成了更好的代码?我可以想象为ctor强制编译器提供体在编译单元中包含一些(空)代码?这对于自动生成的代码也是如此吗?
答案 0 :(得分:11)
如果您不希望您的对象是可复制的,则无需提供实现。只需在没有任何实现的情况下声明copy ctor私有。其他ctors也是如此,如果你不想让任何机构使用它们,只需将它们声明为私有而无需任何实现。
答案 1 :(得分:9)
只要你不使用它们就可以了。
使用0x标准,您可以使用deleted functions。
class X {
// ...
X& operator=(const X&) = delete; // Disallow copying
X(const X&) = delete;
};
答案 2 :(得分:5)
您可以使用仅声明构造函数来禁止给定的构造,例如标准构造或复制构造。
例如,如果要避免复制对象,可以将复制构造函数和赋值运算符声明为私有,并且不要定义它们,那么尝试复制对象的任何人(包括您)都会有链接器错误
关于您的上一次修改: 我期望一个像样的编译器为默认构造函数和空构造函数生成相同的代码而没有初始化列表,最后,它需要做的是对每个成员进行默认初始化。
答案 3 :(得分:2)
如果在不提供实现的情况下声明它们,则不能使用它们,因为它们不存在。如果要使用构造函数,则必须允许编译器通过不声明它们来创建它们,或者必须声明它们并提供实现。
为您不想使用的构造函数提供声明但没有实现有时很有用。这通常是通过对象(例如单例)的复制构造函数来完成的,您不希望它们成为副本。在这种情况下,声明通常也是私密的。
答案 4 :(得分:2)
首先,如果要使您的类完全不可复制,请不要实现私有拷贝构造函数和赋值运算符。否则,一段具有访问权限的代码(方法或朋友)仍然可以默默地进行复制。如果没有实现,您将收到链接器错误。
但是,编译器错误会更好,因为您可以更快地找到错误。为此,有boost::noncopyable
,或者您可以从隐藏其复制构造函数和赋值运算符的基类派生。
关于默认构造函数:如果您声明任何构造函数,编译器将不会生成一个。通常没有必要特别隐藏它。
答案 5 :(得分:0)
如果使用'empty'声明,编译器将不再生成默认实现,您将收到链接错误。如果你声明它们,你必须写它们,所以必须使用空括号形式。
答案 6 :(得分:0)
您需要提供定义。如果不这样做,并且您尝试使用它们,则无法链接。
答案 7 :(得分:0)
这取决于您是否使用这些构造函数。如果您不使用它们,您可能会将它们保留为未定义。如果你使用它们(例如你是从类的静态函数创建类的对象,你需要定义它们)你需要提供定义,否则你将从链接器中得到未解析的外部符号错误。