【发布时间】:2021-03-17 14:56:19
【问题描述】:
我正在尝试使用流畅的界面创建对象配置器。 代码:
class Configurator {
public:
Configurator() {
printf("Constructor.\n");
}
~Configurator() {
printf("Destructor.\n");
printf("String: %s\n", this->str_.c_str());
}
Configurator& Append(const std::string& str) {
this->str_ += str;
return *this;
}
private:
std::string str_;
};
Configurator PrepareConfigurator() {
return Configurator();
}
Configurator PrepareWithSomeAppend() {
return PrepareConfigurator().Append("hello").Append(", ");
}
int main() {
printf("Start.\n");
PrepareWithSomeAppend().Append("world!");
printf("End.\n");
return 0;
}
Class Configurator 仅在析构函数中打印字符串(我想这样做是为了不强制调用辅助方法来调用操作)。 Append 方法将字符串附加到私有字段字符串。
方法PrepareConfigurator 创建Configurator。
方法PrepareWithSomeAppend 调用PrepareConfigurator 并调用Append 方法并从函数返回对象。
在main 中,我再次调用Append 方法,我希望得到这样的输出:
Start.
Constructor.
Destructor.
String: hello, world!
End.
但我得到了输出:
Start.
Constructor.
Destructor.
String: hello,
Destructor.
String: hello, world!
End.
为什么析构函数调用了两次?我该如何预防? 提前致谢!
编辑:
我也尝试在PrepareWithSomeAppend 中创建Configurator,但问题没有解决。析构函数调用了两次。
Configurator PrepareWithSomeAppend() {
return Configurator().Append("hello").Append(", ");
}
另外,我尝试从PrepareWithSomeAppend 返回对Configurator 的引用:
Configurator& PrepareWithSomeAppend() {
return Configurator().Append("hello").Append(", ");
}
而且它也不起作用,析构函数在 PrepareWithSomeAppend 方法中调用本地对象,我在 main 函数中遇到分段错误错误,因为引用指向被破坏的对象。
如何防止在 PrepareWithSomeAppend 函数中调用本地对象的析构函数?还是不复制就返回一个对象?
【问题讨论】:
-
您的对象被复制或移动(编译器为您生成复制和/或移动构造函数 - 抱歉没有阅读详细信息以检查哪个)。
-
不用担心,您看不到另一个构造函数调用,因为它使用的是复制构造函数(隐式生成)。
-
在你的输出语句中打印出
this的值,它会给你一个关于发生了什么的线索。你会看到this是不同的。 -
@MarkRansom 规则三,遵循或,不会改变这里的行为。这里的问题是为什么 RVO 不会在这里发生
标签: c++ oop destructor fluent-interface