const关键字解析

const是恒定不变的意思,也翻译为常量,常数等,很多人都认为被const修饰的值是常量,这是不精确的,应该说是只读的变量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容。

节省空间

编译器通常不为普通const只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。
这里写图片描述
const定义的只读变量从汇编的角度来看,只是给出了对应的内存地址。所以,const定义的只读变量在程序运行中只有一份拷贝。

const修饰的只读变量

定义const只读变量,具有不可变性。

void test(void)
{
    const int Max = 100;
    int Array[Max];
}
int main()
{
    test();
    system("pause");
    return 0;
}

该代码在.c文件中,编译器会提示出错,而在.cpp文件中会顺利运行。这就证明:在C语言中,const修饰的Max仍然是变量,只不过是只读属性。
注意:const修饰的只读变量必须在定义的同时初始化。

修饰一般变量

一般常量是指简单类型的只读变量。这种只读变量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后。

const int a = 10;
int const a = 10;

在C++中,const修饰的变量已经为一个常量,具有宏的属性,即在编译期间,编译器会将const修饰的常量进行替换。

修饰指针

如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
因此,推荐使用int const* p,而不是使用const int* p(虽然两者意义完全一样),这样更容易理解。

int a = 10;
const int* p = &a;            // 指针p可变,指针p指向的内容不能变
int const* p = &a;            // 同上
int* const p = &a;            // 指针p本身不能变,p指向的对象可变
const int* const p = &a;      // 两者都不能变
int const* const p = &a;      // 同上
修饰函数的参数

const修饰符也可以修饰函数的参数,当不希望这个参数值被函数体内意外改变时使用。

void func (const int& n)
{
     n = 10;        // 编译错误 
}
修饰函数的返回值

const也可以修饰函数的返回值,返回值不可被改变。
用const修饰函数返回值的含义和用const修饰普通变量以及指针的含义基本相同。

const int* func()   // 返回的指针所指向的内容不能修改
{
    // return p;
}
修饰引用

以下两种定义形式在本质上是一样的:

int a = 10;
const int& b = a;
int const& b = a;
修饰类成员变量

用const修饰的类成员变量,只能在类的构造函数初始化列表中初始化,不能在类构造函数体内赋值。

class A
{
publicA(int x) : a(x)  // 正确
    {
         //a = x;    // 错误
    }

privateconst int a;
};
修饰类成员函数

用const修饰的类成员函数,实际修饰该成员变量隐含的this指针,在该函数体内不能改变该类对象的任何成员变量, 也不能调用类中任何非const成员函数。

class A
{
public:
    int& getValue() const
    {
        // a = 10;    // 错误
        return a;
    }

private:
    int a;            // 非const成员变量
};

在const修饰的成员函数可能需要对类的某个成员变量进行修改,该成员变量只需被mutable关键字修饰即可。

修饰类对象

用const修饰的类对象,该对象内的任何成员变量都不能被修改。
因此不能调用该对象的任何非const成员函数,因为对非const成员函数的调用会有修改成员变量的企图。

class A
{
 public:
    void funcA() {}
    void funcB() const {}
};

int main
{
    const A a;
    a.funcB();    // 可以
    a.funcA();    // 错误

    const A* b = new A();
    b->funcB();    // 可以
    b->funcA();    // 错误
}

const对象不可以调用非const成员函数,可以调用const成员函数。
非const对象可以调用非const成员函数和const成员函数。
const成员函数内不可以调用非const成员函数,可以调用其他的const成员函数。
非const成员函数内可以调用其他的非const成员函数和const成员函数。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值