为什么在此示例程序中未调用复制构造函数?
当函数input()
返回一个对象时,会生成该对象的副本,但我看不到根据控制台中的输出调用了复制构造函数。
输出:
Enter a string: ssssssssss
ssssssssss
Freeing s
代码:
#include <iostream>
using namespace std;
class Sample {
char *s;
public:
Sample() { s = 0; }
Sample(const Sample &sample) { cout << "copyconstructor\n"; }
~Sample() { if(s) delete[] s; cout << "Freeing s\n"; }
void show() { cout << s << "\n"; }
void set(char *str) {
s = new char[strlen(str) + 1];
strcpy(s, str);
}
};
Sample input() {
char instr[80];
Sample str;
cout << "Enter a string: ";
cin >> instr;
str.set(instr);
return str;
}
int main() {
Sample ob = input();
ob.show();
return 0;
}
答案 0 :(得分:2)
由于编译器已执行优化,因此未调用复制构造函数。
优化称为RVO(或NRVO),并允许编译器在某些情况下直接在调用点处构建返回值。
大多数编译器允许您使用选项启用优化。 Clang和gcc允许你使用:
来转换elision
-fno-elide-constructors
此外,您的代码还有未定义的行为,因为复制构造函数不会初始化 s
。在复制构造对象上调用Sample::show
或析构函数将导致UB访问或删除未初始化的数据未定义。
此外,班级Sample
展示UB,因为它不遵循三法则{>(What is The Rule of Three?)。使用隐式声明的复制赋值运算符将执行s
的浅表副本,这可能导致数据在销毁时被多次删除,即UB。