从可读性和“最少惊喜”的角度来看,我通常更喜欢第二个,但是我承认当参数是临时参数时,第一个可能更有效。
第一个确实会导致没有副本,而不仅仅是单个副本,可以想象这在极端情况下可能是一个真正的问题。
例如,参加这个测试程序。gcc -O3 -S
(gcc 版本 4.4.2 20091222 (Red Hat 4.4.2-20) (GCC)) 生成一个对 B 的复制构造函数的调用,但不为函数调用 A 的复制构造函数f
(赋值运算符对A
和都内联B
)。A
并且B
都可以被视为非常基本的字符串类。分配和复制data
将在构造函数中进行,在析构函数中进行释放。
#include <algorithm>
class A
{
public:
explicit A(const char*);
A& operator=(A val) { swap(val); return *this; }
void swap(A& other) { std::swap(data, other.data); }
A(const A&);
~A();
private:
const char* data;
};
class B
{
public:
explicit B(const char*);
B& operator=(const B& val) { B tmp(val); swap(tmp); return *this; }
void swap(B& other) { std::swap(data, other.data); }
B(const B&);
~B();
private:
const char* data;
};
void f(A& a, B& b)
{
a = A("Hello");
b = B("World");
}