C++中如何无需拷贝即可直接访问类的成员变量
解决方案
你原来的实现会触发拷贝的核心原因是:对传入的外部std::vector<char>引用做了赋值操作,会完整复制内部成员的所有元素到外部vector中。可以通过返回内部成员的引用/指针完全避免拷贝,以下是几种可行方案:
方案1:返回左值引用(兼容性最好,最常用)
直接修改方法返回内部vector的引用,没有任何拷贝开销,C++98及以上版本都支持:
class joint { std::vector<char> m_letters; std::vector<char> f_letters; public: // 只读版本,返回const引用,禁止外部修改内部成员 const std::vector<char>& get_cutting_types(bool flag) const { return flag ? m_letters : f_letters; } // 如果需要允许外部修改内部成员,补充非const版本 std::vector<char>& get_cutting_types(bool flag) { return flag ? m_letters : f_letters; } };
使用方式:
joint j; // 用引用接收返回值,没有任何数据拷贝,直接指向类的内部成员 const auto& letters = j.get_cutting_types(true);
方案2:保留输出参数的形式
如果你的业务逻辑必须保留输出参数的写法,可以把输出参数改为指针引用:
class joint { std::vector<char> m_letters; std::vector<char> f_letters; public: void get_cutting_types(bool flag, const std::vector<char>*& out_ptr) const { out_ptr = flag ? &m_letters : &f_letters; } };
使用方式:
joint j; const std::vector<char>* letters_ptr = nullptr; j.get_cutting_types(true, letters_ptr); // 后续通过letters_ptr访问内部成员,无拷贝
方案3:使用std::reference_wrapper(适合需要存储引用的场景)
如果你需要把返回的引用存储到容器等不支持普通引用的场景,可以用C++11引入的std::reference_wrapper:
#include <functional> class joint { std::vector<char> m_letters; std::vector<char> f_letters; public: std::reference_wrapper<const std::vector<char>> get_cutting_types(bool flag) const { return flag ? std::cref(m_letters) : std::cref(f_letters); } };
注意事项
所有无拷贝的方案都依赖内部成员的生命周期:你必须保证访问返回的引用/指针时,对应的joint类对象还没有被销毁,否则会出现悬空引用/指针的未定义行为。如果需要独立于原对象的副本,再主动执行拷贝即可,灵活性远高于原有强制拷贝的实现。
内容的提问来源于stack exchange,提问作者Petras
相关产品推荐
相关产品推荐

