c – 对构造函数的显式调用

前端之家收集整理的这篇文章主要介绍了c – 对构造函数的显式调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我知道我们可以显式地和隐式地调用构造函数的概念,并且我已经测试了两个场景(通常直到现在我的所有目的通过调用构造函数Implicitlly来实现),但是我想知道每当我们创建对象时隐式调用构造函数那么显式调用构造函数背后的主要原因是什么呢?当我们在隐式调用上显式调用构造函数时,它提供了什么优点或缺点?

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已经指出的那样).并且明确地将转换构造器标记为显式具有在幕后禁止不需要的隐式转换的优点.

原文链接:https://www.f2er.com/c/120154.html

猜你在找的C&C++相关文章