问题描述
我知道这个概念,我们可以调用的构造函数显式
和隐式
,我已经测试了方案(一般到现在我的所有目的通过调用构造函数 Implicitlly
),但我想知道构造函数隐式调用每当我们创建 objects
,,因此,调用构造函数
Explicitly
的主要原因是什么。在隐式调用
?
I know the concept that we can call the Constructor both Explicitly
and Implicitly
, and i have tested both the scenarios(generally till now my all purposes got fulfilled by calling constructor Implicitlly
), but i was wondering that constructor get called implicitly whenever we create objects
,, so what is the main reason behind calling the constructor Explicitly
. What advantage or disadvantage it provides when we call constructor Explicitly
over the Implicit Call
?
示例
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
推荐答案
因为您对 explicit 和隐含的定义与标准定义不匹配(大多数现有答案都基于该定义,在添加包含您自己的定义的示例之前,
There are two different problems here, as your definition of explicit and implicit does not match the standard definition (on which most of the existing answers are based, being written before you added your example containing your own definition of explicit and implicit).
好吧,让我们先看看你的定义 explicit ,因为你明确地写了类型名称,所以它是(我猜你是显式的):
Ok so let's first consider your definition of explicit, which would be (I guess you call it explicit because you explicitly write the type name?):
integer int1 = integer(0, 100);
与 implicit 的定义相对应:
integer int1(1, 100);
在这种情况下,第一个显式优于第二隐含调用的任何优点。但是还是有区别。第一个实际使用双参数构造函数创建一个临时函数,然后使用复制构造函数创建 int1
。虽然在实践中编译器通常会优化掉这个额外的副本,如果你的副本构造函数是私有的,它仍然不会工作,而第二个只需要双参数构造函数(你甚至可以看到这是缺点)。
In this case the first "explicit" call really doesn't have any advantage over the second "implicit" call. But there is still a difference. The first one actually creates a temporary using the two-argument constructor, which is then used to create int1
using the copy constructor. Although in practice the compiler will usually optimize away this additional copy, it still won't work if your copy constructor is private, whereas the second one only needs the two-argument constructor (you could even see this as disadvantage).
但现在对于显式和隐式的实际标准定义。 显式构造函数调用是任何构造函数调用,好的,显式调用。实际上,每当你使用括号语法()
来创建一个对象,你显式地调用一个构造函数,否则它是一个隐式的构造函数调用可以说,由编译器在幕后完成):
But now to the actual standard definitions of explicit and implicit. An explicit constructor call is any constructor call you, well, explicitly call. Practically speaking, whenever you use the brace-syntax ()
to create an object you explicitly call a constructor, otherwise it's an implicit constructor call (so to say, being done behind the scenes by the compiler):
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
是默认construtor和任何单参数构造函数(包括复制和移动构造函数)。在这方面的一个特殊问题是单参数构造函数不是复制/移动构造函数:
So the only constructors that can be called implicitly are the default construtor and any one-argument constructors (including copy and move constructors). A special problem in this regard are one-argument constructors not being copy/move constructors:
struct integer
{
integer(int);
};
这允许编译器 imlicitly 调用构造函数来转换类型,因此任何 int
都可以隐式转换为 integer
:
This allows the compiler to imlicitly call the the constructor to convert types, thus any int
is implicitly convertible to integer
:
void func(integer);
func(42); // implicit call to int-constructor
为了禁止这种行为,你必须标记构造函数 explicit
:
To disallow such behaviour you would have to mark the constructor explicit
:
struct integer
{
explicit integer(int);
};
这只允许明确调用 c> func(integer(42)))(但我猜你已经知道了)。这具有的优点是它不会在幕后引入未注意/不想要的转换,这可导致各种难以找到关于重载分辨率的问题和模糊性。因此,通常的做法是标记任何转换构造函数(单参数非复制/移动构造函数) explicit
,最有可能也是为什么C ++ 11最终引入 explicit
转换运算符。
Which only allows it to be called explicitly (e.g. func(integer(42))
) (but I guess you already knew this). This has the advantage that it doesn't introduce unnoticed/unwanted conversions behind the scenes, which can lead to all kinds of hard to find problems and ambiguities regarding overload resolution. It is therefore usual practice to mark any conversion constructors (one-argument non-copy/move constructors) explicit
, and most probably also the reason why C++11 finally introduced explicit
conversion operators.
定义和示例,使用 integer int1 = integer(1,100);
而不是真的没有优势integer int1(1,100);
So to sum up, according to your definition and example, there is really no advantage in using integer int1 = integer(1, 100);
instead of integer int1(1, 100);
, though it makes a (usually irrelevant) difference.
但根据标准定义,显式构造函数调用由于显式地实际构造对象的唯一方式是使用显式构造函数调用,而 隐式构造函数调用 只在某些情况下在场景之后完成,并且只对零和一参数构造函数(如已经指出的aschepler )工作。明确标记转换构造函数为 explicit
具有在后台禁止不必要的隐式转换的优点。
But according to the standard definitions, explicit constructor calls have plenty advantages over implicit ones, since the only way to actually construct an object explicitly is to use a, well, explicit constructor call, whereas implicit constructor calls are only done behind the scenes in certain situations and only work for zero- and one-argument constructors (as aschepler already pointed out). And explicitly marking conversion constructors as explicit
has the advantage of disallowing unwanted implicit conversions behind the scenes.
这篇关于显式调用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!