C++ 构造函数语法

2021-12-30 00:00:00 constructor c++

一个简单的问题:以下语句是否等效?还是第二个在幕后做了更多隐含的事情(如果是这样,是什么?)

Simple question: are the following statements equivalent? or is the second one doing more implicit things behind the scenes (if so, what?)

myClass x(3);
myClass x = myClass(3);

谢谢!

推荐答案

它们并不完全相同.第一个称为直接初始化",而第二个称为复制初始化".

They are not completely identical. The first is called "direct initialization" while the second is called "copy initialization".

现在,标准制定了两条规则.第一个用于直接初始化和复制初始化,其中初始化器是已初始化对象的类型.第二条规则用于其他情况下的副本初始化.

Now, the Standard makes up two rules. The first is for direct initialization and for copy initialization where the initializer is of the type of the initialized object. The second rule is for copy initialization in other cases.

因此,从这个角度来看,两者都被称为一个 - 第一个 - 规则.如果您具有相同类型的副本初始化,则允许编译器省略副本,因此它可以将您创建的临时对象直接构造到初始化对象中.所以你可以很好地结束生成相同的代码.但是复制构造函数,即使复制被省略(优化掉),也必须仍然可用.即,如果您有一个私有复制构造函数,那么如果它出现的代码无法访问它,那么该代码就是无效的.

So, from that point of view both are termed in one - the first - rule. In the case where you have copy initialization with the same type, the compiler is allowed to elide a copy, so it can construct the temporary you create directly into the initialized object. So you can end up very well with the same code generated. But the copy constructor, even if the copy is elided (optimized out), must still be available. I.e if you have a private copy constructor, that code is invalid if the code in which it appears has no access to it.

第二种称为复制初始化,因为如果初始化器的类型是不同的类型,则会创建一个临时对象,试图将右侧隐式转换为左侧:

The second is called copy-initialization, because if the type of the initializer is of a different type, a temporary object is created in trying to implicitly convert the right side to the left side:

myclass c = 3;

编译器创建一个 myclass 类型的临时对象,然后当有一个接受 int 的构造函数时.然后它用那个临时对象初始化对象.同样在这种情况下,临时创建的可以直接在初始化对象中创建.您可以通过在类的构造函数/析构函数中打印消息并为 GCC 使用选项 -fno-elide-constructors 来执行这些步骤.它不会尝试删除副本.

The compiler creates a temporary object of the type of myclass then when there is a constructor that takes an int. Then it initializes the object with that temporary. Also in this case, the temporary created can be created directly in the initialized object. You can follow these steps by printing messages in constructors / destructors of your class and using the option -fno-elide-constructors for GCC. It does not try to elide copies then.

顺便提一下,上面的代码与赋值运算符无关.在这两种情况下,发生的都是初始化.

On a side-note, that code above has nothing to do with an assignment operator. In both cases, what happens is an initialization.

相关文章