空类的默认构造函数是公共的。但是怎么做?
Posted
技术标签:
【中文标题】空类的默认构造函数是公共的。但是怎么做?【英文标题】:Default constructor of an Empty Class is public. But how? 【发布时间】:2013-08-07 12:21:29 【问题描述】:我有一个简单的问题:
class my
;
my ob;
编译器允许我创建一个有意义的对象。而且,我知道你不能在构造函数是私有的地方创建对象。
在我看来,类中的所有内容都是private
,但显然不是默认构造函数(因为它允许我创建对象,因为默认构造函数应该是public
)。但令我困惑的是,课堂上没有public
部分。
那么,在这种情况下,它是否创建一个public
部分只是为了在其下放置一个默认构造函数?
还是发生了其他事情而我的理由不正确?
此外,在创建/访问对象时,如何在内部组织/跟踪公共、私有和受保护的访问?
我收到了这个问题,因为我之前从未创建过空类的对象。
【问题讨论】:
编译器提供的构造函数、析构函数和赋值运算符是public
。你必须积极地做一些事情来禁止它们。
【参考方案1】:
如果您自己不声明任何构造函数,C++ 编译器将始终为您生成一个公共的普通构造函数。不仅如此,它还会隐式创建一个公共复制构造函数和赋值运算符。
来自 C++11 标准 12.1.5:
如果 类 X 没有用户声明的构造函数,隐式声明了没有参数的构造函数 作为默认值。隐式声明的默认构造函数是其类的内联公共成员。
和 12.8.7、12.8.11:
如果类定义没有显式声明复制构造函数,则隐式声明。 [...] 隐式声明的副本 [...] 构造函数是其类的内联公共成员。
最后是 12.8.18、12.8.20、12.8.22:
如果类定义没有显式声明复制赋值运算符,则隐式声明。 [...]如果类 X 的定义没有显式声明移动赋值运算符,则将隐式 宣布[...]。隐式声明的 复制/移动赋值运算符是其类的内联公共成员。
请注意,仅在某些情况下才会生成移动赋值运算符,这超出了本问题的范围,有关详细信息,请参阅 12.8.20。
如果你想要一个私有构造函数,你必须自己声明它:
class my my() ;
如果您想阻止复制构造函数或赋值运算符的生成,您可以声明但不实现它们:
class my my(my const &); ;
或者,从 C++11 开始,显式删除它们:
class my my(my const &) = delete; ;
【讨论】:
【参考方案2】:是的,编译器会将默认构造函数、默认复制构造函数和默认赋值运算符生成为“public”——因为其他任何事情都会使类变得毫无用处......
当然,那些构造函数会相当简单——事实上,它可以被替换为“nothing”,因为构造一个空类将什么都不做。
【讨论】:
【参考方案3】:编译器生成的默认构造函数(和其他运算符)自动公开。如果您希望默认构造函数是私有的,那么您需要在类的私有部分中声明它自己指定它。
私有、受保护和公共的概念仅与编译器相关。它们没有任何意义,并且在运行时不会被跟踪。
【讨论】:
【参考方案4】:如果用户没有定义,编译器会生成默认构造函数inline public
,C++ draft standard
的相关部分是12.1/5
:
如果类 X 没有用户声明的构造函数,则没有参数的构造函数被隐式声明为默认 (8.4)。隐式声明的默认构造函数是其类的内联公共成员。
【讨论】:
【参考方案5】:通常编译器在创建对象时默认生成 4 个东西。
默认构造函数
复制构造函数
复制赋值运算符
析构函数
例如:
class First
First() //default constructor
First(const First &) //copy constructor
First& operator=(const First&) //Copy assignment operator
return *this;
~First() //Destructor
这些是隐式内联公共成员,除非没有用户声明的构造函数。
【讨论】:
以上是关于空类的默认构造函数是公共的。但是怎么做?的主要内容,如果未能解决你的问题,请参考以下文章