在 C++ 中仅对空私有构造函数使用声明是否正确?

发布于 2024-08-11 15:35:00 字数 331 浏览 9 评论 0原文

例如,这是正确的:

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

还是您应该提供定义:

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

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

For example is this correct:

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

or you should rather provide definition(s):

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

?
Thanks for the current answers. Let's extend this question - does compiler generate better code in one of this examples? I can imagine that providing body for ctor forces compiler to include some (empty) code in compilation unit? Is this also true for auto-generated code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

故事灯 2024-08-18 15:35:00

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

If you do not wish your object to be copyable, then there is no need to provide the implementation. Just declare the copy ctor private without any implementation. The same holds for other ctors, if you do not want any body to use them, just declare them private without any implementation.

葬シ愛 2024-08-18 15:35:00

只要你不使用它们就可以。

通过 0x 标准,您可以使用已删除的函数

class X {
   // ...
   X& operator=(const X&) = delete; // Disallow copying
   X(const X&) = delete;
};

It is fine as long as you don't use them.

With the 0x standard you can use deleted functions.

class X {
   // ...
   X& operator=(const X&) = delete; // Disallow copying
   X(const X&) = delete;
};
夏の忆 2024-08-18 15:35:00

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

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

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

You may use declaration-only constructors to disallow given constructions, like standard construction, or copy-construction.

For example, if you want to avoid your object being copied you can declare as private the copy-constructor and the assignment operator and do not define them, then anyone,including you, who tries to copy the object will have linker errors.

About your last edit:
I'd expect a decent compiler to produce the same code for a default constructor and for an empty constructor and no initialization list, in the end, what it needs to do is default-initialize each member.

堇色安年 2024-08-18 15:35:00

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

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

If you declare them without providing implementation, then you can't use them because they don't exist. If you want to use the constructors, you must either allow the compiler to create them by not declaring them, OR you must declare them and provide an implementation.

It is occasionally useful to provide a declaration but no implementation for a constructor that you don't want used. This is often done with the copy constructor for objects (such as singletons) that you don't want there to be copies of, ever. In such cases, the declaration is often made private as well.

╰沐子 2024-08-18 15:35:00

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

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

关于默认构造函数:如果您声明任何构造函数,编译器将不会生成默认构造函数。一般来说没有必要专门隐藏这一点。

Firstly, if you want to make your class completely non-copyable, don't implement the private copy constructor and assignment operator. Otherwise it is still possible that a piece of code that has access (a method or a friend) can silently make copies. Without the implementation, you'll get a linker error.

However, a compiler error would be preferable, as you'll find out about the error faster. For this there's boost::noncopyable, or you can derive from a base class that hides its copy constructor and assignment operator.

Concerning the default constructor: the compiler will not generate one if you declare any constructor at all. There's generally no need to hide that specifically.

倾城月光淡如水﹏ 2024-08-18 15:35:00

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

If you use the 'empty' declaration, the compiler will no longer generate the default implementation and you will get link errors. If you declare them, you have to write them so the empty-brace form is necessary.

感情废物 2024-08-18 15:35:00

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

You will need to provide definitions. If you do not, and you attempt to use them, it will fail to link.

小霸王臭丫头 2024-08-18 15:35:00

这取决于您是否使用这些构造函数。如果您不使用它们,则可以将它们保留为未定义。如果您使用它们(例如,您正在从类的静态函数创建类的对象,您需要定义它们),您需要提供定义,否则您将从链接器中收到无法解析的外部符号错误。

That depends on whether you use these constructors or not. If you don't use them you may leave them undefined. If you use them (for example you are creating objects of the class from static functions of class, you need to define them) you need to provide definitions, otherwise you'll get unresolved external symbols error from linker.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文