C++类成员函数:使用私有getter/setter还是直接操作私有数据?
C++类成员实现:私有Getter/Setter vs 直接操作原始数据,及Complex类代码评审
核心问题解答:私有Getter/Setter vs 直接操作原始数据
在类内部成员函数中选择哪种方式,核心取决于类的未来演化需求:
- 如果后续可能修改内部存储结构(比如把
double换成高精度数值类型),或者需要在读写数据时添加校验、日志、同步逻辑,那么私有Getter/Setter能大幅降低后续修改成本——只需修改这几个函数,不用遍历所有成员函数修改直接访问的代码。 - 如果确定类的内部存储不会变更(比如Complex类的实部虚部永远是
double),直接操作私有成员变量会更高效(虽然编译器通常会优化掉简单函数调用,但代码更直白简洁)。
Complex类代码具体评审建议
- 友元函数参数缺失const:
Re和Im仅读取对象值,参数应改为const Complex &z,否则无法接受const类型的Complex对象,导致const Complex c(1,2); Re(c);这类代码编译失败。 - 运算符参数的const修正:
operator -=和operator /=的参数不需要修改原对象,应声明为const Complex &,避免调用方传入const对象时出错。 - operator/=的逻辑bug:当前实现会修改传入的
divisor对象(因为divisor *= ~divisor直接修改了原变量),这完全不符合用户预期。正确做法是计算除数的模平方,不修改原除数:Complex &Complex::operator /=(const Complex &divisor){ double mod_sq = divisor.re() * divisor.re() + divisor.im() * divisor.im(); *this *= ~divisor; set_real_part(re() / mod_sq); set_imaginary_part(im() / mod_sq); return *this; } - 构造函数优化:使用成员初始化列表:替代构造函数内调用setter的方式,避免默认初始化后再赋值的冗余操作,更符合C++最佳实践:
Complex::Complex() : real_part_(0), imaginary_part_(0) {} Complex::Complex(const double &real_part) : real_part_(real_part), imaginary_part_(0) {} Complex::Complex(const double &real_part, const double &imaginary_part) : real_part_(real_part), imaginary_part_(imaginary_part) {} - 私有Getter/Setter的冗余性:如果你的Getter仅简单返回成员变量、Setter仅直接赋值,且短期内无存储结构变更计划,这些私有函数属于冗余代码,直接访问
real_part_和imaginary_part_会让代码更简洁。例如operator+=可简化为:Complex &Complex::operator +=(const Complex &other){ real_part_ += other.real_part_; imaginary_part_ += other.imaginary_part_; return *this; } - 语法细节修正:私有成员函数定义末尾无需加分号(如
double re() const {return real_part_;};的分号可删除),虽不影响编译,但不符合编码规范。
内容的提问来源于stack exchange,提问作者Eric Cardozo
相关产品推荐
相关产品推荐

