1. 问题背景与核心挑战
在C++开发中,我们经常遇到一个经典难题:当一个类需要存储某个值时,这个值可能来自左值(lvalue)也可能来自右值(rvalue)。这种场景下该如何设计类的成员变量存储方式?这看似简单的问题背后隐藏着C++对象生命周期的关键机制。
左值通常指有持久存储位置的表达式(如变量),而右值通常是临时对象或字面量。举个例子:
cpp复制std::string s = "hello"; // s是左值
processString(std::string{"world"}); // 临时string是右值
问题的核心矛盾在于:
- 如果存储为引用(如
const T&),可以避免拷贝但无法安全绑定临时对象 - 如果存储为值类型,可以接收右值但处理左值时会产生不必要的拷贝
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统解决方案的局限性
2.1 引用存储方案分析
使用const引用存储看似优雅:
cpp复制class MyClass {
public:
explicit MyClass(const std::string& s) : s_(s) {}
private:
const std::string& s_;
};
这种方案对左值工作良好:
cpp复制std::string s = "hello";
MyClass obj1(s); // 正确:引用绑定到已有对象
但对于右值会导致悬垂引用:
cpp复制MyClass obj2(getString()); // 危险:临时对象立即销毁
通过生命周期测试可以清晰看到问题:
cpp复制struct Tracker {
~Tracker() { std::cout << "Destroyed\n"; }
};
MyClass obj(Tracker{}); // 输出"Destroyed"
obj.useTracker(); // 使用已销毁对象!
2.2 值存储方案分析
改用值存储可以解决右值问题:
cpp复制class MyClass {
public:
explicit MyClass(std::string s) : s_(std::move(s)) {}
priv
