std::string引用类成员的异常行为问题求助
三段C++代码的输出差异原因解析
第一段代码及运行结果
#include <iostream> class Foo { public: Foo(const std::string& label) : label_(label) {} void print() { std::cout << label_; } private: const std::string& label_; }; int main() { auto x = new Foo("Hello World"); x->print(); }
运行输出:
Hello World!
第二段代码及运行结果
// g++ -o test test.cpp -std=c++17 #include <iostream> class Base { public: Base(const std::string& label) : label_(label) {} void print() { std::cout << label_; } private: const std::string& label_; }; class Derived : public Base { public: Derived(const std::string& label) : Base(label) {} }; int main() { auto x = new Derived("Hello World"); x->print(); }
运行输出:
Hello World
第三段代码及运行结果
// g++ -o test test.cpp -std=c++17 #include <iostream> class Base { public: Base(const std::string& label) : label_(label) {} void print() { std::cout << label_; } private: const std::string& label_; }; class Derived : public Base { public: Derived() : Base("Hello World") {} }; int main() { auto x = new Derived(); x->print(); }
运行输出:无任何内容
差异原因分析
核心问题在于临时std::string对象的生命周期与类成员引用的绑定规则:
第一段代码:
构造Foo对象时,字符串字面量"Hello World"会隐式生成临时std::string对象,该对象绑定到构造函数的const std::string& label参数。根据C++标准,当临时对象绑定到构造函数参数、且该参数用来初始化类的成员引用时,临时对象的生命周期会被延长至整个类对象的生命周期。因此调用print()时,label_引用的对象仍然有效,能正常输出内容。第二段代码:
构造Derived对象时,临时std::string对象先绑定到Derived构造函数的const std::string& label参数,再通过引用传递给Base的构造函数,最终初始化Base的成员引用label_。这里临时对象的生命周期同样被延长至整个Derived对象的生命周期(引用传递链条保留了临时对象的绑定关系),所以print()能正常访问有效对象,输出正确内容。第三段代码:
Derived的构造函数直接以"Hello World"作为参数调用Base的构造函数,此时临时std::string对象仅在Base构造函数的调用表达式中存在——Base构造函数执行完毕后,这个临时对象就会被立即销毁。而Base的成员label_是绑定到已销毁对象的悬空引用,后续调用print()访问悬空引用属于未定义行为(可能输出乱码、崩溃或无输出),这就是没有任何输出的原因。
内容的提问来源于stack exchange,提问作者morpheus
相关产品推荐
相关产品推荐

