构造函数或赋值运算符

Jul*_*pov 5 c++ copy-constructor assignment-operator

你能帮助我吗C++标准中的定义描述了在这种情况下哪一个将被称为构造函数或赋值运算符:

#include <iostream>

using namespace std;

class CTest
{
public:

 CTest() : m_nTest(0)
 {
  cout << "Default constructor" << endl;
 }

 CTest(int a) : m_nTest(a)
 {
  cout << "Int constructor" << endl;
 }

 CTest(const CTest& obj)
 {
  m_nTest = obj.m_nTest;
  cout << "Copy constructor" << endl;
 }

 CTest& operator=(int rhs)
 {
  m_nTest = rhs;
  cout << "Assignment" << endl;
  return *this;
 }

protected:
 int m_nTest;
};

int _tmain(int argc, _TCHAR* argv[])
{
 CTest b = 5;

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者只是编译器优化的问题?

Kon*_*lph 11

int在这种情况下,它始终是默认构造函数.这称为隐式转换,在语义上等效于以下代码:

CTest b(5);
Run Code Online (Sandbox Code Playgroud)

从不在初始化中调用赋值运算符.考虑以下情况:

CTest b = CTest(5);
Run Code Online (Sandbox Code Playgroud)

在这里,我们int显式调用构造函数(取一个),然后将结果赋值给b.但再次,没有赋值运算符永远调用.严格地说,两种情况都会在创建类型的对象后调用复制构造函数CTest.但事实上,该标准积极鼓励编译器在这里优化复制构造函数调用(§12.8/ 15) - 实际上,现代C++编译器不会在这里发出copycon调用.

  • +1,但我会尽量避免在'默认构造函数采用int'的句子中使用'default'.我认为只是说'int构造函数'或'构造函数采用int'会更清楚.默认在标准中具有特定含义(无参数). (4认同)

小智 7

这里发生的事情取决于您的编译器.它可以使用int构造函数创建一个临时对象,然后从该临时文件复制构造b.但是,它很可能会忽略复制构造函数调用.在任何情况下都不会使用赋值运算符.


vis*_*tor 5

CTest b = 5;与 完全相同CTest b(CTest(5));涉及两个构造函数:一个采用 an int(从整数 5 隐式转换),另一个是复制构造函数。这里根本不涉及赋值运算符。

编译器很可能会优化掉不必要的副本,因此结果就像您输入了CTest b(5). 因此,在运行时,无论看到“复制构造函数”被打印(带有该-fno-elide-constructors选项的 GCC)还是不被打印(GCC 默认情况下)都将是程序的有效输出。

然而,从概念上讲,编译器需要检查是否存在可访问且合适的复制构造函数。如果 a)复制CTest b = 5;构造函数是私有/受保护的(不可访问)或 b) 复制构造函数通过非常量引用获取参数(不能接受来自的临时变量CTest(5)- VC++ 可能将其视为非),则该表单将无法编译- 标准编译器扩展,不过)。

士气是:没有简单的方法可以通过查看代码来判断程序中复制构造函数被调用的位置和次数。复制通常可以被省略,因此您永远不应该依赖复制构造函数的副作用。如果它做了它应该做的事情,那么编译器是否消除了一些不必要的复制构造函数调用对您来说并不重要。