4

例如这是正确的:

class C 
{
   private: 
     C();
     C(const & C other);
}

或者您应该提供定义:

class C 
{
   private: 
     C() {};
     C(const & C other) {};
}

? 感谢您提供当前的答案。让我们扩展这个问题 - 编译器是否会在其中一个示例中生成更好的代码?我可以想象为 ctor 提供正文会强制编译器在编译单元中包含一些(空)代码?自动生成的代码也是如此吗?

4

8 回答 8

11

如果您不希望您的对象可复制,则无需提供实现。只需将复制 ctor 声明为私有,无需任何实现。其他 ctors 也是如此,如果您不希望任何机构使用它们,只需将它们声明为私有而不进行任何实现。

于 2009-11-13T11:59:47.980 回答
9

只要您不使用它们就可以了。

使用 0x 标准,您可以使用已删除的功能

class X {
   // ...
   X& operator=(const X&) = delete; // Disallow copying
   X(const X&) = delete;
};
于 2009-11-13T12:08:20.400 回答
5

您可以使用仅声明构造函数来禁止给定构造,例如标准构造或复制构造。

例如,如果您想避免您的对象被复制,您可以将复制构造函数和赋值运算符声明为私有并且不定义它们,那么任何尝试复制对象的人(包括您)都会遇到链接器错误。

关于您的最后一次编辑:我希望一个体面的编译器能够为默认构造函数和空构造函数且没有初始化列表生成相同的代码,最后,它需要做的是默认初始化每个成员。

于 2009-11-13T11:59:07.623 回答
2

如果您在没有提供实现的情况下声明它们,那么您将无法使用它们,因为它们不存在。如果要使用构造函数,则必须允许编译器通过不声明它们来创建它们,或者必须声明它们并提供实现。

提供声明但不为您不想使用的构造函数提供实现有时很有用。这通常通过您不希望有副本的对象(例如单例)的复制构造函数来完成。在这种情况下,声明通常也是私有的。

于 2009-11-13T12:00:58.727 回答
2

首先,如果您想让您的类完全不可复制,请不要实现私有复制构造函数和赋值运算符。否则,一段具有访问权限的代码(方法或朋友)仍然有可能默默地进行复制。如果没有实现,您将收到链接器错误。

但是,编译器错误会更好,因为您会更快地发现错误。为此,有boost::noncopyable, 或者您可以从隐藏复制构造函数和赋值运算符的基类派生。

关于默认构造函数:如果您声明任何构造函数,编译器将不会生成一个。通常没有必要专门隐藏它。

于 2009-11-13T16:55:20.413 回答
0

如果您使用“空”声明,编译器将不再生成默认实现,您将收到链接错误。如果你声明它们,你必须写它们,所以空括号形式是必要的。

于 2009-11-13T11:57:21.603 回答
0

您将需要提供定义。如果您不这样做,并且您尝试使用它们,它将无法链接。

于 2009-11-13T11:57:58.093 回答
0

这取决于您是否使用这些构造函数。如果你不使用它们,你可能会让它们未定义。如果你使用它们(例如你从类的静态函数创建类的对象,你需要定义它们)你需要提供定义,否则你会从链接器中得到未解析的外部符号错误。

于 2009-11-13T11:58:29.123 回答