[Effective C++]条款03:尽可能使用const

1、const关键字
const关键字常用于定义常量,表示某个值、对象或指针在程序运行期间不可修改,也用于修饰函数,引用等.
2、常量
用于定义不可修改的变量,必须在定义时初始化。

const int x = 10;
// x = 20; // 错误:x是常量,不可修改

3、常量指针与指针常量
3.1)、常量指针(Pointer to Constant):指针指向的值不可修改,但指针本身可以指向其他地址。

  • const在星号左边
const int* ptr = &x;
// *ptr = 20; // 错误:ptr指向的值不可修改
int y = 30;
ptr = &y; // 正确:ptr可以指向其他地址

3.2)、指针常量(Constant Pointer):指针本身不可修改,但可以通过指针修改指向的值。

int* const ptr = &x;
*ptr = 20; // 正确:可以通过ptr修改x的值
// ptr = &y; // 错误:ptr是常量,不可指向其他地址

3.3)、常量指针常量(Constant Pointer to Constant):指针本身和指针指向的值都不可修改。

const int* const ptr = &x;
// *ptr = 20; // 错误:ptr指向的值不可修改
// ptr = &y; // 错误:ptr是常量,不可指向其他地址

4、常量引用
用于定义不可修改的引用。常用于函数参数,避免拷贝大对象。

int x = 10;
const int& ref = x;
// ref = 20; // 错误:ref是常量引用,不可修改

void test(const std::string &txt){...}

5、const与函数
5.1)、const修饰函数参数
表示函数内部不会修改该参数的值。

void func(const int x) {
    // x = 20; // 错误:x是常量,不可修改
}

5.2)、const修饰函数返回值
const可以修饰函数的返回值,表示返回值是常量,不可修改。

const int getValue() {
    return 10;
}

int main() {
    const int x = getValue();
    x = 20; // 错误:x是常量,不可修改
}

5.3)、const成员函数
const成员函数表示该函数不会修改类的成员变量。const成员函数只能调用其他const成员函数。

class MyClass {
public:
    int value;
    void setValue(int v) { value = v; }
    int getValue() const { return value; } // const成员函数
};

int main() {
    const MyClass obj;
    obj.setValue(10); // 错误:obj是常量对象,不能调用非const成员函数
    int x = obj.getValue(); // 正确:可以调用const成员函数
}

5.4)、const函数重载
const可以用于区分函数重载。

class MyClass {
public:
    void func() { // 非const成员函数
        std::cout << "Non-const func\n";
    }

    void func() const { // const成员函数
        std::cout << "Const func\n";
    }
};
常量对象只能调用const成员函数。
const MyClass obj1;
obj1.func(); // 调用const版本,输出:"Const func"

非常量对象优先调用非const成员函数。
MyClass obj2;
obj2.func(); // 调用非const版本,输出:"Non-const func"

6、const与类
6.1)、常量成员变量

  • 必须在构造函数初始化列表中初始化。
class MyClass {
public:
    const int value;
    MyClass(int v) : value(v) {}
};

6.2)、static静态常量成员

  • 使用static const定义类的静态常量成员。
class MyClass {
public:
    static const int value = 10;
};

6.3)、mutable

  • 即使对象是const,mutable成员变量仍然可以被修改。
class MyClass {
public:
    mutable int cache;
    int getValue() const {
        cache++; // 正确:cache是mutable
        return cache;
    }
};

7、const与智能指针

  • const可以修饰智能指针本身或指向的值。
const std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
// ptr1 = nullptr; // 错误:ptr1是常量
// *ptr1 = 20;     // 正确:ptr1指向的值可以修改

std::unique_ptr<const int> ptr2 = std::make_unique<const int>(10);
// *ptr2 = 20;     // 错误:ptr2指向的值是常量

8、const与容器
const可以修饰容器本身或容器中的元素。容器内的元素值不可修改

const std::vector<int> vec = {1, 2, 3};
// vec[0] = 10; // 错误:vec是常量,元素不可修改

9、const与constexpr

  • constexpr用于定义编译期常量。
constexpr int x = 10; // 编译期常量
const int y = 20;     // 运行时常量

10、为什么要尽量多使用const

  • 提高代码的可读性和安全性。
  • 防止意外修改数据。
  • 支持常量对象和常量表达式。
  • 优化性能(如避免拷贝大对象)。

思维导图笔记:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值