【C++】深入理解const成员

引言

在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;
    }
};

const修饰规则

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%的对象状态错误。
  • 提升接口设计的清晰度。
  • 增强多线程环境下的安全性。
  • 帮助编译器生成更优化的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烛九_阴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值