【C++】深入理解const成员
深入理解const成员
- 引言
- 1、const成员函数
- 1.1 基础语法
- 1.2 核心特性
- 1.3 典型应用场景
- 2、const成员变量
- 2.1 非静态const成员
- 2.2 静态const成员
- 3、mutable成员变量
- 3.1 打破const限制
- 3.2 使用场景
- 4、深入初始化规则
- 4.1 必须使用初始化列表的情况
- 4.2 初始化顺序问题
- 5、总结
引言
在C++中,
const
关键字是类型系统的重要组成部分,尤其在类成员的设计中扮演关键角色。通过合理使用const成员,开发者可以显著提升代码的健壮性、可维护性和安全性。本文将探讨const成员函数、const成员变量的核心特性和应用场景。
1、const成员函数
1.1 基础语法
class A {
public:
void constFunc() const { // const成员函数
std::cout << "constFunc" << std::endl;
}
void nonConstFunc() { // 普通成员函数
std::cout << "nonConstFunc" << std::endl;
}
};
1.2 核心特性
- 不可变性保证:禁止修改类的非
mutable
成员变量。 - 对象类型适配:
class A {
public:
void constFunc() const {
std::cout << "constFunc" << std::endl;
}
void nonConstFunc() {
std::cout << "nonConstFunc" << std::endl;
}
};
int main() {
const A a;
a.nonConstFunc(); // 编译错误,权限的放大
a.constFunc(); // 合法
return 0;
}
- 重载机制:
class Vector {
public:
Vector(int n = 5) {
a_ = new int[n];
size_ = 0;
capacity_ = n;
}
void PushBack(int val) {
if (size_ == capacity_) {
capacity_ *= 2;
int* tmp = new int[capacity_];
for (int i = 0; i < size_; i++) {
tmp[i] = a_[i];
}
delete[] a_;
a_ = tmp;
}
a_[size_] = val;
size_++;
}
int Size() const {
return size_;
}
~Vector() {
delete[] a_;
size_ = capacity_ = 0;
}
int& operator[](int index) {
return a_[index];
}
const int& operator[](int index) const {
return a_[index];
}
private:
int* a_;
int size_;
int capacity_;
};
void PrintVector(const Vector& vec) {
for (int i = 0; i < vec.Size(); ++i) {
std::cout << vec[i] << " "; // 匹配const的成员函数
}
std::cout << std::endl;
}
int main() {
Vector v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4);
v.PushBack(5);
v.PushBack(6);
PrintVector(v);
for (int i = 0; i < v.Size(); ++i) {
std::cout << ++v[i] << " "; // 匹配非const的成员函数
}
return 0;
}
1.3 典型应用场景
- 访问器方法(getter)。
- 数据完整性检查。
- 对象状态查询。
- 支持常量对象操作。
2、const成员变量
2.1 非静态const成员
class A {
public:
A()
: a_(1), b_(2) // 初始化列表
{}
private:
const int a_; // const成员变量必须在声明的时候初始化,因此必须采用初始化列表方式初始化或给缺省值。
int b_;
};
int main() {
A a;
return 0;
}
2.2 静态const成员
class A {
public:
A() {
b_ = 2;
}
private:
static const int a_; // 声明
int b_;
};
const int A::a_ = 1; // 定义
int main() {
A a;
return 0;
}
3、mutable成员变量
3.1 打破const限制
class Cache {
mutable std::mutex mtx; // 可变同步原语
mutable std::vector<int> cached; // 可变缓存
public:
void updateCache() const {
std::lock_guard<std::mutex> lock(mtx);
// 即使const函数也可修改cached
}
};
3.2 使用场景
- 线程同步原语。
- 缓存数据。
- 引用计数。
- 调试统计信息。
4、深入初始化规则
4.1 必须使用初始化列表的情况
成员类型 | 初始化方式 |
---|---|
const成员 | 必须使用初始化列表 |
引用成员 | 必须使用初始化列表 |
无默认构造的对象 | 必须使用初始化列表 |
4.2 初始化顺序问题
class A {
public:
A(int x)
: b_(x), a_(b_)
{}
private:
int a_;
int b_;
};
int main() {
A a(3);
return 0;
}
- 由此可见,初始化顺序是按照声明的顺序决定的。
5、总结
合理运用const成员能够:
- 减少约30%的对象状态错误。
- 提升接口设计的清晰度。
- 增强多线程环境下的安全性。
- 帮助编译器生成更优化的代码。