C++ 函数中的局部变量应该如何初始化?

C++ 函数中的局部变量应该如何初始化?,c++,C++,函数中的局部变量应该如何初始化?出于性能原因,我应该这样做吗 Point2D point(1,2); Point2D point = Point2D(1,2); 还是像这样 Point2D point(1,2); Point2D point = Point2D(1,2); 这有关系吗?不,没关系。两者都将导致调用同一个构造函数。不,这不重要。这两种方法都会导致对同一个构造函数的调用。您应该使用第一种方法,因为如果使用第二种方法,我相信编译器会执行比需要更复杂的操作。我认为它会创建一个临时

函数中的局部变量应该如何初始化?出于性能原因,我应该这样做吗

Point2D point(1,2);
Point2D point = Point2D(1,2);
还是像这样

Point2D point(1,2);
Point2D point = Point2D(1,2);

这有关系吗?

不,没关系。两者都将导致调用同一个构造函数。

不,这不重要。这两种方法都会导致对同一个构造函数的调用。

您应该使用第一种方法,因为如果使用第二种方法,我相信编译器会执行比需要更复杂的操作。我认为它会创建一个临时对象来表示右侧,然后使用复制构造函数将值复制到左侧的对象


这一点我可能错了,所以请检查您的程序集列表。

您应该使用第一种方法,因为如果使用第二种方法,我相信编译器会执行一些不必要的复杂操作。我认为它会创建一个临时对象来表示右侧,然后使用复制构造函数将值复制到左侧的对象


我可能错了,所以请检查您的程序集列表。

第一个只调用构造函数,而第二个先调用构造函数,然后将其复制到point。因此,您应该使用第一个,因为它不会启动复制操作。

第一个只调用构造函数,而第二个调用构造函数,然后将其复制到point。因此,您应该使用第一个,因为它不会启动复制操作。

是的,这很重要。第一个版本Point2D point1,2将调用构造函数,而第二个版本Point2D point=Point2D1,2将首先创建一个新的Point2D,即右边的Point2D,然后调用复制构造函数来实际创建点。正如你所看到的,这是C++和java之间的一个很大的区别。第一个版本Point2D point1,2将调用构造函数,而第二个版本Point2D point=Point2D1,2将首先创建一个新的Point2D,即右边的Point2D,然后调用复制构造函数来实际创建点。正如你所看到的,这是C++和java或C.< /P> < P>的一个很大的差别。大多数时候返回值优化会使这两个选项从性能的角度看起来足够相似,特别是如果你有一个定义了/P>的移动赋值操作符的话。 有其他的事情要考虑。

如果您的类型具有空构造函数,则执行此操作会有问题:

Point2D p(); // instead of Point p;
这就是我们所知道的。可以通过使用第二种形式来避免:

Point2D p = Point2D();
或者使用最新标准中引入的统一初始化语法:

Point2D p{};

大多数时候,返回值优化将使这两个选项从性能角度来看足够相似,特别是在定义了移动分配操作符的情况下

有其他的事情要考虑。

如果您的类型具有空构造函数,则执行此操作会有问题:

Point2D p(); // instead of Point p;
这就是我们所知道的。可以通过使用第二种形式来避免:

Point2D p = Point2D();
或者使用最新标准中引入的统一初始化语法:

Point2D p{};

第二个不是调用了复制构造函数吗?@Paul:可以,但是大多数启用了优化的编译器都不会调用,请参见“复制省略”。这是直接初始化和复制初始化之间的根本区别。@ildjarn编译器“修复”了代码的问题这一事实并不重要。如果不进行优化,第二个版本的速度可能是第一个版本的两倍,而且肯定不会以任何方式使用C++语言@保罗:第二种方式不是惯用的,没有争论。但是,OP关心的是性能,所以他当然会对其进行优化。@DavidGrayson:Copy ellision是该标准允许的例外情况之一,编译器可以对其进行优化以消除副作用。这就是为什么你永远不应该依赖复制构造函数中的副作用。第二个不是调用了复制构造函数吗?@Paul:可以,但大多数编译器在启用了优化的情况下是不会调用的。另请参见“复制省略”。这是直接初始化和复制初始化之间的根本区别。@ildjarn编译器“修复”了代码的问题这一事实并不重要。如果不进行优化,第二个版本的速度可能是第一个版本的两倍,而且肯定不会以任何方式使用C++语言@保罗:第二种方式不是惯用的,没有争论。但是,OP关心的是性能,所以他当然会对其进行优化。@DavidGrayson:Copy ellision是该标准允许的例外情况之一,编译器可以对其进行优化以消除副作用。这就是为什么您永远不应该依赖复制构造函数中的副作用。我相信编译器将使用临时对象调用复制构造函数,而不是调用赋值运算符。我认为性能方面的差异只是创建临时对象的开销,我认为在大多数CA中这是微不足道的
谢谢,我编辑了我的答案,将=运算符更改为复制构造函数。在未优化模式下,可能会有一个复制构造函数调用。在优化模式下,可能不会。@Macke:在您观察到这种行为的地方,您使用的是什么编译器?如果你所说的是真的,那听起来真的很糟糕,因为这意味着你可能会意外地编写行为不同的代码,这取决于所启用的优化。我想试着复制一下。@DavidGrayson:注意“可能”这个词。OTOH,大家都知道复制elison可能会发生,是的,这可能会有不同的表现。但这在标准中规定为符合性行为,因为它不影响程序的感知结果,即少一份。如果你在每个ctor中打印一些内容,你会看到什么时候会发生这种情况。这与RVO/NVRO复制省略非常相似,RVO/NVRO复制省略在按值返回对象时跳过复制构造函数。我相信编译器将使用临时对象调用复制构造函数,而不是调用赋值运算符。我认为性能方面的差异只是创建临时对象的开销,我认为这在大多数情况下是无关紧要的。谢谢,我编辑了我的答案,将=运算符更改为复制构造函数。在未优化模式下,可能会有一个复制构造函数调用。在优化模式下,可能不会。@Macke:在您观察到这种行为的地方,您使用的是什么编译器?如果你所说的是真的,那听起来真的很糟糕,因为这意味着你可能会意外地编写行为不同的代码,这取决于所启用的优化。我想试着复制一下。@DavidGrayson:注意“可能”这个词。OTOH,大家都知道复制elison可能会发生,是的,这可能会有不同的表现。但这在标准中规定为符合性行为,因为它不影响程序的感知结果,即少一份。如果你在每个ctor中打印一些内容,你会看到什么时候会发生这种情况。这与RVO/NVRO复制省略非常相似,RVO/NVRO复制省略在按值返回对象时跳过复制ctor。