允许 C++ 删除副本。这是在返回值优化中完成的。
更新!
原来我错了!
在某一点上我是对的,但 C++ 委员会在 1997 年否认了编译器的优化。无论我记得哪个编译器这样做都是过时的,或者做错了,或者可能决定无视委员会。 (我当然看不出有任何理由需要额外的副本!)
在更新的总结中,C++ 只允许省略(删除)复制构造函数操作,用于返回值优化以及抛出和接收异常对象。
更新 2
我又错了?显然我无法正确阅读标准文档?
GCC 和 Microsoft cl.exe 都生成结果,无需额外的临时副本。
这是我的测试代码,全部微软化:
#include <stdio.h>
#include <tchar.h>
class A {
int m;
public:
A(int x=0) : m(x)
{
_putts(_T("Constructor A"));
}
A(const A &x) : m(x.m)
{
_putts(_T("Copy A"));
}
int get() const { return m; }
};
class B {
A m;
public:
B(int y=5) : m(y)
{
_putts(_T("Constructor B"));
}
B(const B &x) : m(x.m)
{
_putts(_T("Copy B"));
}
B(A x) : m(x)
{
_putts(_T("Construct B from A value"));
}
int get() const { return m.get(); }
};
class C {
A m;
public:
C(int y=5) : m(y)
{
_putts(_T("Constructor C"));
}
C(const C &x) : m(x.m)
{
_putts(_T("Copy C"));
}
C(const A &x) : m(x)
{
_putts(_T("Construct C from A reference"));
}
int get() const { return m.get(); }
};
int _tmain(int argc, _TCHAR* argv[])
{
_putts(_T("Hello World"));
int i = 27;
if( argc > 1 )
i = _tstoi(argv[0]);
A aval(i);
_tprintf(_T("A value is: %d\n"), aval.get());
B bval( aval );
_tprintf(_T("Value is: %d\n"), bval.get());
B bval2( (A(i)) );
_tprintf(_T("Value is: %d\n"), bval2.get());
C cval( aval );
_tprintf(_T("Value is: %d\n"), cval.get());
C cval2( (A(i)) );
_tprintf(_T("Value is: %d\n"), cval2.get());
_putts(_T("Goodbye World"));
return 0;
}
使用它来替换 GCC 的 de-Microsofting 的包含:
#include <cstdio>
#include <cstdlib>
using namespace std;
#define _TCHAR char
#define _T(x) x
#define _tmain main
#define _putts puts
#define _tprintf printf
#define _tstoi atoi
这是两个编译器的输出:
Hello World
Constructor A
A value is: 27
Copy A
Copy A
Construct B from A value
Value is: 27
Constructor A
Copy A
Construct B from A value
Value is: 27
Copy A
Construct C from A reference
Value is: 27
Constructor A
Copy A
Construct C from A reference
Value is: 27
Goodbye World