C++ const

[TOC]

#1. Const values

1.1 Const修饰变量

const关键字修饰的变量为常量,编译器会阻止它被修改。被const修饰的变量必须初始化。

int main()
{
    const int value1 = 5; // Copy initialization
    const int value2(7); // Direct initialization
    const int value3{ 9 }; // Uniform initialization(C++11)

    value1 = 10;   // C3892
    value1++;   // C2105
}

在C++中,可以通过const关键字来定义常量而不是通过#define预处理器伪指令来定义。被const修饰的变量可以用作常量表达式。

// compile with: /c
const int maxarray = 255;
char store_char[maxarray];  // allowed in C++; not allowed in C

1.2 Const修饰指针

const可以用于修饰指针变量. const修饰指针变量有两种情况,一种是修饰指针所指向的变量;另一种是修饰指针本身。

Const Pointer

Const Point(常量指针),指向常量的指针。意味着指针所指向的是常量,它指向的内容不能发生改变。但是指针本身是可以变化的。

声明
Type const * pvar_name;
const Type * pvar_name;
示例
int main()
{
    int a = 1, b = 2;
    const int *pi = &a;
    printf("A=%d", *pi);
    *pa = 10; // C3892,指针指向常量不能被修改
    
    pi = &b; // 指针变量本身被修改
    printf("B=%d", *pi);
    system("pause");
} 
Pointer Const

Pointer Const(指针常量),指针本身就是常量。意味着指针里面所存储的内容(内存地址)是常量,不能改变。但是,内存地址所对应的内容是可以通过指针改变的。

声明
Type * const pvar_name;
示例
int main()
{
    int a = 1, b = 2;
    int * const pi = &a;
    *pi = 10; // 指针所指向的变量可以被修改
    printf("A=%d", *pi);
    pi = &b; // C3892,指针变量本身不能被修改
} 

#2. Const class objects and member functions

2.1 Const classes

一旦被const修饰的类对象初始化完成,任何尝试对类的非const成员和方法进行访问都是不允许的。

class Date {
public:
    Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
    int GetMonth();
    void SetMonth(int mn);
private:
    int year;
    int day;
    int month;
};

int Date::GetMonth() {
    return month;
}

void Date::SetMonth(int mn) {
    month = mn;
}

int main()
{
    const Date date{ 2022,03,03 };
    date.SetMonth(4); // C2662
    auto month = date.GetMonth(); // C2662
}

2.2 Const member functions

被const修饰的类对象,只能访问类的const成员变量和成员函数。被const修饰的成员函数能确保其不会修改调用它的对象,并且也只能访问同为const的成员函数。为了声明一个函数为const成员函数只需要在其参数列表后面,函数体之前加上const关键字。

class Date {
public:
    Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
    int GetMonth() const; // A read-only function,note addtion of const keyword after parameter list but before function body.
    void SetMonth(int mn); // A write function;can't be const.
private:
    int year;
    int day;
    int month;
};

int Date::GetMonth() const {
    return month;
}

void Date::SetMonth(int mn) {
    month = mn;
}

int main()
{
    Date curDate{ 2022,05,27 };
    const Date birthDate{ 2022,03,03 };
    curDate.SetMonth(4);
    auto birMn = birthDate.GetMonth(); // Const member function access by const class object.
    std::cout << birMn << std::endl;
    birthDate.SetMonth(10); // C2662, non-const member function cannot be called by const object.
    auto curMn = curDate.GetMonth(); // const member function access by non-const class object.
    std::cout << curMn << std::endl;
} 

被const修饰的的成员函数,意味着隐藏的this指针*this所获取的也是const对象。意味着函数体内能访问的任何成员都是const的。const成员函数只能返回const成员引用。

被const修饰的成员函数可以被任意的对象(const或者non-const class object)调用,const对象或者non-const对象,但是non-const函数只能被non-const对象调用。

2.3 Overloading const and non-const function

同一函数可以通过添加const实现函数重载。

class Date {
public:
    Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
    int GetMonth() const; // GetMonth for const class objects(return const reference)
    int GetMonth(); // GetMonth for non-const class objects(return non-const reference)
    void SetMonth(int mn);
private:
    int year;
    int day;
    int month;
};

int Date::GetMonth() const {
    return month;
}

int Date::GetMonth() {
    return month;
}

void Date::SetMonth(int mn) {
    month = mn;
}

你可能感兴趣的:(C++ const)