例
class integer { int m,n; public: integer (int x,int y); }; integer :: integer (int x,int y ) { m=x; n = y; }
现在如果我打电话的话
integer int1 = integer( 0,100); // Explicit Call integer int1(1,100); // implicit call
解决方法
好的,让我们首先考虑你的显式定义,这是(我想你明确地称它为显式,因为你明确地写了类型名称?):
integer int1 = integer(0,100);
与你隐含的定义相对应:
integer int1(1,100);
在这种情况下,第一个“显式”调用与第二个“隐式”调用相比没有任何优势.但仍然存在差异.第一个实际上使用双参数构造函数创建临时,然后使用复制构造函数创建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
因此,可以隐式调用的唯一构造函数是默认构造函数和任何单参数构造函数(包括复制和移动构造函数).这方面的一个特殊问题是单参数构造函数不是复制/移动构造函数:
struct integer { integer(int); };
这允许编译器隐式调用构造函数来转换类型,因此任何int都可以隐式转换为整数:
void func(integer); func(42); // implicit call to int-constructor
struct integer { explicit integer(int); };
这只允许它被显式调用(例如func(integer(42)))(但我想你已经知道了).这样做的优点是它不会在幕后引入未被注意/不需要的转换,这可能导致各种难以找到的有关重载决策的问题和含糊之处.因此,通常的做法是将任何转换构造函数(单参数非复制/移动构造函数)显式标记,并且很可能也是C 11最终引入显式转换运算符的原因.
总而言之,根据你的定义和例子,使用整数int1 = integer(1,100)确实没有优势;而不是整数int1(1,100);,虽然它产生(通常不相关)差异.
但是根据标准定义,显式构造函数调用比隐式构造调用具有更多优势,因为实际构造对象的唯一方法是使用一个良好的显式构造函数调用,而隐式构造函数调用仅在幕后进行.情况,只适用于零参数和单参数构造函数(正如aschepler已经指出的那样).并且明确地将转换构造器标记为显式具有在幕后禁止不需要的隐式转换的优点.