其他答案建议只有一个过载 operator =(String rhs)
按价值计数,但这是 不是 最有效的实施。
的确,在此示例中,戴维·罗德里格斯(DavidRodríguez)
String f();
String a;
a = f(); // with String& operator=(String)
没有副本。但是,假设 operator =(String rhs)
提供并考虑此示例:
String a("Hello"), b("World");
a = b;
发生的是
b
被复制到 rhs
(内存分配 + memcpy
);
a
和 rhs
被交换;
rhs
被摧毁。
如果我们实施 operator =(const String& rhs)
和 operator =(String&& rhs)
然后,当目标的长度大于源时,我们可以避免步骤1中的内存分配。例如,这是一个简单的实现(不完美:如果 String
有一个 capacity
成员):
String& operator=(const String& rhs) {
if (len < rhs.len) {
String tmp(rhs);
swap(tmp);
else {
len = rhs.len;
memcpy(data, rhs.data, len);
data[len] = 0;
}
return *this;
}
String& operator =(String&& rhs) {
swap(rhs);
}
除了性能点 swap
是 noexcept
, , 然后 operator =(String&&)
可 noexcept
也是。 (如果记忆分配是“潜在的”执行的,情况并非如此。)
在这个优秀的情况下查看更多细节 解释 霍华德·辛南特(Howard Hinnant)。