这是完整的例子(源码:C ++ From Ground Up,3rd Edition,page 219-320):
class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { cout << "s: " << s <<" ,Freeing s\n"; if(s) delete [] s;}
void show() { cout << s << "\n"; }
void set(char *str);
sample operator=(const sample &ob); // overload assignment
};
// Normal constructor.
sample::sample() {
s = new char('\0'); // s points to a null string.
cout << "Normal constructor: s: " << strlen(s) << endl;
}
// Copy constructor.
sample::sample(const sample &ob) {
cout << "Copy constructor: ob.s: "<< ob.s << " ,strlen(ob.s): " << strlen(ob.s) << "\n";
s = new char[strlen(ob.s)+1];
strcpy(s, ob.s);
}
// Load a string.
void sample::set(char *str) {
s = new char[strlen(str)+1];
strcpy(s, str);
}
// Overload assignment operator.
sample sample::operator=(const sample &ob) {
/* If the target memory is not large enough
then allocate new memory. */
cout << "operator= strlen(ob.s): " << strlen(ob.s) << " ,strlen(s): " << strlen(s) << endl;
if(strlen(ob.s) > strlen(s)) {
cout << "operator= Larger memory of target object. Deleting current...\n";
delete [] s;
s = new char[strlen(ob.s)+1];
}
strcpy(s, ob.s);
return *this;
}
// Return an object of type sample.
sample input() {
char instr[80];
static sample str;
cout << "Enter a string: ";
cin >> instr;
str.set(instr);
return str;
}
int main() {
sample ob;
// assign returned object to ob
ob=input(); // This is now OK
ob.show();
return 0;
}
但是我不明白为什么两次次复制构造函数被调用。 (运行代码后输出)
Normal constructor: s:
Normal constructor: s:
Enter a string: Hello
Copy constructor: ob.s: Hello ,strlen(ob.s): 5
operator= strlen(ob.s): 5 strlen(s): 0
operator= Larger memory of target object. Deleting current...
Copy constructor: ob.s: Hello ,strlen(ob.s): 5
s: Hello, Freeing s
s: Hello, Freeing s
Hello
s: Hello, Freeing s
s: Hello, Freeing s
我知道当 input()函数返回时调用它,并创建临时对象(通过调用复制构造函数),但我不知道为什么第二次,因为我知道(但是也许我错了)复制构造函数 NOT 调用赋值操作,但看起来,尽管如此,当 return * this; 被调用时(当重载运算符返回值时) ),复制构造函数被调用? 我错过了什么?
Thankx
答案 0 :(得分:1)
代码非常糟糕。更不用说其他错误,这就是复制构造函数被调用两次的原因。
首次从input()
返回一个对象,因为它是静态的并且按值返回,所以不能应用RVO。
第二次调用是return *this;
中operator=()
的结果,因为出于某种原因,它还会按值返回一个对象:
sample operator=(const sample &ob);
// ^^^