显式调用构造函数

Tej*_*dra 7 c++ constructor

我知道,我们可以调用构造函数并重的理念Explicitly,并Implicitly和我已经测试这两种方案(通常到现在我所有的目的得到了通过调用构造函数实现Implicitlly),但我想知道,每当我们创建一个构造函数得到隐式调用objects,,等什么是调用构造函数的主要原因Explicitly.它提供了什么优势或劣势,当我们调用构造ExplicitlyImplicit Call

class integer
{
   int m ,n;
 public:
   integer (int x , int y); 
};
integer :: integer (int x , int y )
{
   m=x; n = y;
}
Run Code Online (Sandbox Code Playgroud)

现在如果我打电话的话

integer int1 = integer( 0 , 100); //  Explicit Call
integer int1(1,100); // implicit call
Run Code Online (Sandbox Code Playgroud)

Chr*_*ica 16

这里有两个不同的问题,因为你的显式隐式定义与标准定义不匹配(大多数现有答案都基于这个定义,在你添加包含你自己的显式隐式定义的例子之前编写).

好的,让我们首先考虑你的显式定义,这是(我猜你称之为显式,因为你明确地写了类型名称?):

integer int1 = integer(0, 100);
Run Code Online (Sandbox Code Playgroud)

与你对隐含的定义相对应:

integer int1(1, 100);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,第一个"显式"调用与第二个"隐式"调用相比没有任何优势.但仍然存在差异.第一个实际上使用双参数构造函数创建临时,然后使用int1复制构造函数创建它.虽然在实践中编译器通常会优化掉这个额外的副本,但是如果你的拷贝构造函数是私有的,它仍然不会工作,而第二个只需要双参数构造函数(你甚至可以看作是缺点).


但现在对显式隐式的实际标准定义.一个明确的构造函数调用任何构造函数调用你,好,显式调用.实际上,每当你使用brace-syntax ()创建一个对象时你显式地调用一个构造函数,否则它是一个隐式的构造函数调用(所以说,由编译器在幕后完成):

integer int1;                   // implicit default constructor
integer int1(1, 100);           // explicit two-arg constructor
integer int1 = integer(0, 100); // explicit two-arg constructor, implicit copy constructor

void func(integer);             // function taking by-value
func(int1);                     // implicit copy constructor
Run Code Online (Sandbox Code Playgroud)

因此,可以隐式调用的唯一构造函数是默认构造函数和任何单参数构造函数(包括复制和移动构造函数).这方面的一个特殊问题是单参数构造函数不是复制/移动构造函数:

struct integer
{
    integer(int);
};
Run Code Online (Sandbox Code Playgroud)

这允许编译器隐式调用构造函数来转换类型,因此任何int可以隐式转换为integer:

void func(integer);
func(42);             // implicit call to int-constructor
Run Code Online (Sandbox Code Playgroud)

要禁止此类行为,您必须标记构造函数explicit:

struct integer
{
    explicit integer(int);
};
Run Code Online (Sandbox Code Playgroud)

这只允许它被明确调用(例如func(integer(42)))(但我想你已经知道了).这样做的优点是它不会在幕后引入未被注意/不需要的转换,这可能导致各种难以找到的有关重载决策的问题和含糊之处.因此,通常的做法是标记任何转换构造函数(单参数非复制/移动构造函数)explicit,并且很可能也是C++ 11最终引入explicit转换运算符的原因.


总而言之,根据你的定义和例子,使用integer int1 = integer(1, 100);而不是使用integer int1(1, 100);它确实没有优势,尽管它会产生(通常是不相关的)差异.

但根据标准的定义,明确的构造函数调用有过很多优点隐含的,因为实际上构造一个对象的唯一办法明确是使用一个,好了,明确的构造函数的调用,而隐式构造函数调用仅在某些幕后做情况,只适用于零参数和单参数构造函数(正如aschepler已经指出的那样).并明确标记转换构造函数explicit的优点是不允许在幕后进行不必要的隐式转换.