C++ const常量

Const(常量)

const 关键字在C和C++中是一个非常有用的工具,帮助开发者编写更加健壮和安全的代码。它可以用于:

  1. 防止变量的值被意外修改。
  2. 保护指针指向的数据不被修改。
  3. 保证函数参数在函数内部不被修改。
  4. 确保类成员函数不修改对象的状态。

定义一个不可修改的变量

const int x = 10;

const指针

指向常量的指针(const T* ptr)

const int value = 10;
const int* ptr = &value;

int anotherValue = 20;
ptr = &anotherValue; // 合法,指针本身可以修改

*ptr = 30; // 非法,不能通过该指针修改指向的数据

这种情况表示指针指向的内容是常量,不能通过该指针修改指向的数据,但指针本身可以修改,指向其他数据

常量指针或指针常量(T* const ptr)

int value = 10;
int* const ptr = &value;

*ptr = 20; // 合法,可以通过该指针修改指向的数据

int anotherValue = 30;
ptr = &anotherValue; // 非法,不能修改指针本身

指针本身是常量,不能修改指针的值,但是可以通过该指针修改指向的数据。

指向常量的指针常量(const T* const ptr)

const int value = 10;
const int* const ptr = &value;

*ptr = 20; // 非法,不能通过该指针修改指向的数据

int anotherValue = 30;
ptr = &anotherValue; // 非法,不能修改指针本身

这种情况指针和指针指向都是常量,指针本身和指向的数据都不能修改。

* 指向常量对象的指针(const Objcet)

class MyClass {
public:
    MyClass(int v) : value(v) {}
    int getValue() const { return value; }
    void setValue(int v) { value = v; }

private:
    int value;
};

const MyClass obj(10);
const MyClass* ptr = &obj;

std::cout << ptr->getValue() << std::endl; // 合法,可以调用 const 成员函数

ptr->setValue(20); // 非法,不能调用非 const 成员函数

与基本类型类似 指向常量对象的指针不能通过该指针调用修改对象状态的成员函数。

const在类中的使用

const成员函数

class MyClass {
public:
    void display() const {
        // 不能修改成员变量
    }
private:
    int value;
};

确保成员函数不会修改对象的状态。

const成员变量

class MyClass {
public:
    MyClass(int val) : constValue(val) {}
private:
    const int constValue;
};

定义一旦对象创建就不可修改的成员变量。

mutable 关键字

class MyClass {
public:
    int getValue() const {
        if (!cacheValid) {
            cachedValue = computeValue();
            cacheValid = true;
        }
        return cachedValue;
    }
private:
    mutable int cachedValue;
    mutable bool cacheValid;
};

允许在 const 成员函数中修改成员变量。

用于更复杂的情况。

const修饰函数参数

void printValue(const int value) {
    std::cout << value << std::endl;
    // value = 5; // 非法,不能修改 const 参数
}

当一个函数参数被 const 修饰时,表示在函数体内不能修改该参数的值。这种做法的主要优点是防止在函数体内意外修改传入的参数,同时提高了函数的可读性(自文档性),表明该参数在函数内不会被改变。

const修饰返回值

class MyClass {
public:
    MyClass(const std::string& name) : name(name) {}

    const std::string& getName() const {
        return name;
    }

private:
    std::string name;
};

const 可以用来修饰返回值,特别是在返回引用或指针时,确保返回的对象不能通过该引用或指针修改。

更详细的实例

#include <iostream>
#include <string>

class User {
public:
    User(const std::string& username) : username(username) {}

    void setUsername(const std::string& newUsername) {
        username = newUsername;
    }

    const std::string& getUsername() const {
        return username;
    }

    void printUsername() const {
        std::cout << "Username: " << getUsername() << std::endl;
    }

private:
    std::string username;
};

int main() {
    User user("john_doe");
    user.printUsername();  // 输出: Username: john_doe

    user.setUsername("jane_doe");
    user.printUsername();  // 输出: Username: jane_doe

    const std::string& name = user.getUsername();
    std::cout << "Retrieved Username: " << name << std::endl;  // 输出: Retrieved Username: jane_doe

    // name = "hacker";  // 非法,不能修改 const 引用

    return 0;
}

const实现原理

  1. 编译时检查:编译器在编译阶段会对所有 const 声明进行检查,确保变量、指针、成员函数、参数和返回值在被声明为 const 后不会被修改。
  2. 类型系统:编译器会将 const 变量、指针、成员函数、参数和返回值视为类型系统的一部分,从而在类型检查时确保常量性。例如,在 const 成员函数中,编译器会将 this 指针视为 const Type* const
  3. 生成错误:如果在代码中尝试修改 const 声明的元素,编译器会生成编译错误,阻止不合法的修改操作。

const和define预编译指令优缺点

const#define 都可以用于定义常量,但它们的实现机制和适用场景不同。const 提供了类型安全和作用域控制,适合用于复杂和大型项目中。而 #define 提供了简单的文本替换,适合用于小型和快速开发的场景。选择哪种方式取决于具体的需求和代码风格。

const 相比于 define 优点

const 提供比 #define 更好的类型安全,原因包括:

  • 类型检查const 具有完整的类型信息,编译器可以进行类型检查,确保类型一致性。
  • 作用域控制const 遵循 C++ 的作用域规则,避免了全局命名冲突的问题,而define是全局的容易造成意外的替换。
  • 内存管理const 常量在内存中有明确的类型,有助于编译器进行优化。

const在调试时也比define更加方便 例如:类型错误时const报错会定位到具体行数 而define只会定义到define那句话。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇