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调用.
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++ 可能将其视为非),则该表单将无法编译- 标准编译器扩展,不过)。
士气是:没有简单的方法可以通过查看代码来判断程序中复制构造函数被调用的位置和次数。复制通常可以被省略,因此您永远不应该依赖复制构造函数的副作用。如果它做了它应该做的事情,那么编译器是否消除了一些不必要的复制构造函数调用对您来说并不重要。