从方法返回MyResult类后,ok_成员变量值异常(应为false却输出true)
我定义了一个包含布尔类型和string类型成员的MyResult类:
#ifndef RESULT_P #define RESULT_P #include <string> #include <utility> class MyResult { public: MyResult() = default; MyResult( const bool& ok, std::string msg) : ok_(ok), msg_(std::move(msg)) {} explicit MyResult(bool ok) : ok_(ok) {} explicit MyResult(std::string msg) : ok_(false), msg_(std::move(msg)) {} bool ok() const { return ok_; } void ok(bool ok) { ok_ = ok; } const std::string &msg() const { return msg_; } void msg(const std::string &msg) { msg_ = msg; } private: bool ok_ { false }; std::string msg_; }; #endif
然后我实现了一个返回MyResult的函数:
MyResult do_something() { if ( something ) { //code } else { return MyResult("something wrong happened"); } }
当我调用auto result = do_something()后,预期进入else分支时返回的对象ok()应该是false,但实际用cout << result.ok() << endl;输出的是true。这是哪里出问题了?
问题分析
你的问题大概率是**未定义行为(Undefined Behavior)**导致的:
当something条件为true时,do_something()函数的if分支里没有编写return语句来返回一个MyResult对象。根据C++标准,非main函数如果声明了返回值类型,但函数执行到末尾却没有执行return语句,属于未定义行为。这时候函数返回的对象的成员值是不确定的——可能是随机的内存值,刚好你的情况里ok_被读取为true。
另外可以确认的是,explicit MyResult(std::string msg)构造函数本身是正确的:它明确将ok_初始化为false,只要进入else分支返回这个构造的对象,ok()一定会返回false。所以问题肯定出在if分支没有返回值的情况。
解决方案
你需要确保do_something()函数在所有代码路径上都返回一个有效的MyResult对象:
如果
something为true时操作成功,返回一个ok_为true的对象:MyResult do_something() { if ( something ) { // 执行成功逻辑 return MyResult(true); // 或者带成功信息:MyResult(true, "success") } else { return MyResult("something wrong happened"); } }如果你希望
if分支也返回ok_为false的对象,也要明确返回:MyResult do_something() { if ( something ) { // 执行某些逻辑,但结果仍为失败 return MyResult("some other error"); } else { return MyResult("something wrong happened"); } }
无论哪种情况,都要保证函数的每一条执行路径都有明确的return语句返回MyResult对象,避免未定义行为。
内容的提问来源于stack exchange,提问作者Captain Nemo

