C++ const对象、常成员函数与常引用详解
01 const对象
当需要定义一个值不可变的对象时,可以在对象声明前添加 const 关键字。这样就能防止对象被意外修改。
class DataModel {
public:
void UpdateValue() {}
private:
int value_;
};
const DataModel obj; // 声明一个const对象
02 常成员函数
在类的成员函数声明后添加 const 关键字,即可将其定义为常成员函数。
- 常成员函数内不能修改类成员变量的值(静态成员变量除外)
- 常成员函数内不能调用同类的非const成员函数(静态成员函数除外)
class Calculator {
public:
int Compute() const { // 常成员函数
// value_ = 0; // 编译错误:不能修改成员变量
// Process(); // 编译错误:不能调用非const函数
return value_;
}
void Process() {}
private:
int value_ = 10;
};
int main() {
const Calculator calc;
// calc.Process(); // 编译错误:const对象不能调用非const成员函数
int result = calc.Compute(); // 正确:const对象可以调用常成员函数
return 0;
}
03 常成员函数的重载
当两个成员函数具有相同的名称和参数列表,但其中一个带有 const 而另一个没有时,它们被视为重载函数。
class ConfigManager {
public:
ConfigManager() : data_(1) {}
int GetValue() const { // 常成员函数版本
return data_;
}
int GetValue() { // 普通成员函数版本
return data_ * 2;
}
private:
int data_;
};
int main() {
const ConfigManager constConfig;
std::cout << "常对象调用: " << constConfig.GetValue() << std::endl;
ConfigManager normalConfig;
std::cout << "普通对象调用: " << normalConfig.GetValue() << std::endl;
return 0;
}
// 输出:
// 常对象调用: 1
// 普通对象调用: 2
04 常引用
在引用前添加 const 关键字,即可创建常引用。通过常引用无法修改所引用变量的值。
int value = 5;
const int & ref = value;
// ref = 10; // 编译错误:不能通过常引用修改变量
value = 8; // 正确:可以直接修改原始变量
将对象作为函数参数时,会调用拷贝构造函数,这可能导致效率下降。使用指针作为参数虽然可以避免拷贝,但代码可读性较差。
更好的解决方案是使用对象引用作为参数,从而避免拷贝构造函数的调用:
class Resource {
public:
Resource() : id_(0) {}
// 其他成员函数
private:
int id_;
};
void HandleResource(Resource & res) {
// 直接使用引用,避免拷贝
}
然而,直接使用对象引用作为参数存在安全隐患:函数内部可能不小心修改实参的值。为了确保安全,可以使用常引用:
void SafeHandle(const Resource & res) {
// 通过常引用访问对象,确保不会被修改
}
使用常引用作为参数,既能避免拷贝带来的性能开销,又能防止函数内部无意中修改实参,是一种推荐的做法。