C++的那些事:const用法面面观
作者:网络转载 发布时间:[ 2014/5/5 11:25:07 ] 推荐标签:C++ const
这里再强调一点,const只是给编译器看的,我们可以很轻松的骗过编译器,并看看编译器都做了什么:
1 const int var = 42;
2 int* p = (int*)&var;
3 *p = 20;
4 cout << var << endl; //42
5 cout << *p << endl; //20
我们在代码的第2行,用一个类型转换强制的,把一个非const指针指向了一个const对象。
但是后面我们通过这个指针来修改这个值,却没有生效,原因呢?
那是因为编译器在编译阶段发现var是一个常量,所以在编译目标代码时已经将var的地方都用42进行了替换。
六、const与类
其实类定义的对象,与普通的变量是一样的,用const修饰时,说明这个类是一个常量类对象,这个对象有下面2个特点:
1)不能改变其成员变量(非mutalbe成员)
2)不能调用其非const成员函数
1 class AClass{
2 public:
3 int m_var;
4 mutable int m_mutable_var;
5 void setVar(int var){ m_var = var; }
6 void printVar(){ cout << m_var; }
7 void printVar_const()const { cout << m_var; }
8 };
9
10 const AClass ac;
11 ac.m_var = 20; // Error:ac是一个const类,不能修改成员变量
12 ac.m_mutable_var = 42; // ok 可以修改mutable修饰的变量
13 ac.setVar(20); // Error: ac不能调用非const成员函数,而且这个成员函数还修改了成员变量的值
14 ac.printVar();// Error:ac不能调用非const成员函数
15 ac.printVar_const(); // ok
七、const与类的成员
1,const成员变量
const 成员变量指的是类中的成员变量为只读,不能够被修改(包括在类外部和类内部)。
1)const 成员变量必须在类的构造函数初始化表达式中被初始化,即使在构造函数体内也不可以。
2)静态 const 成员变量需要在类外部单独定义并初始化(可定义在头文件)
1 class constTestClass
2 {
3 public:
4 const int var;
5 static const int sci;
6 public:
7 constTestClass() :var(42){} // const成员变量必须在类的构造函数初始化列表中初始化
8 };
9 const int constTestClass::sci = 42; // static const成员变量需要在类外单独进行定义和初始化
类对象的实例化过程可以理解为包含以下步骤:首先,开辟整个类对象的内存空间。之后,根据类成员情况,分配各个成员变量的内存空间,并通过构造函数的初始化列表进行初始化。后,执行构造函数中的代码。由于 const 成员变量必须在定义(分配内存空间)时,进行初始化。所以需要在够在函数的初始化列表中初始化。const成员在初始化之后,其值不允许改变了,即便在构造内部也是不允许的。
静态成员变量并不属于某个类对象,而是整个类共有的。静态成员变量可以不依附于某个实例化后的类对象进行访问。那么,静态成员变量的值,应该在任何实例化操作之前,能够进行改变(否则,只有实例化至少一个对象,才能访问静态成员)。所以,静态成员变量不能够由构造函数进行内存分配,而应该在类外部单独定义,在实例化任何对象之前,开辟好空间。又由于 const 成员变量 必须初始化,所以静态成员变量必须在定义的时候初始化。
2,const成员函数
const成员函数指的是,此函数不应该修改任何成员变量。
1)传给const成员函数的this指针,是指向 const 对象 的 const 指针。
2)const成员函数,不能够修改任何成员变量,除非成员变量被 mutable 修饰符修饰。
1 class constTestClass
2 {
3 public:
4 int var;
5 const int ci;
6 mutable int mci;
7 public:
8 void setVar(int i);
9 void setMci(int i)const;
10 };
11 void constTestClass::setVar(int i)
12 {
13 var = i; // ok
14 mci = i; // ok
15 ci = i; // Error:ci是一个const对象不能修改
16 }
17 void constTestClass::setMci(int i)const
18 {
19 var = i; // ok
20 mci = i; // ok mutable成员变量可以被const成员函数修改
21 ci = i; // Error
22 }
在成员函数调用的过程中,都有一个 this 指针被当做参数隐性地传递给成员函数(可能通过栈,也可能通过CPU寄存器)。这个this指针,指向调用这个函数的对象(这样,成员函数才能找到成员变量的地址,从而对其进行操作)。这个this指针,是个 const指针,不能修改其指向(你不希望这个对象的函数,修改了那个对象的成员变量,对吧?)。
传递给const成员函数的this指针,指向一个const对象。也是说,在const成员函数内部,这个this指针是一个指向const对象的const指针。
mutable 修饰符使得const函数的行为有了一些灵活性。相当于提醒编译器,这个成员变量比较特殊,不要进行任何只读检查了。
为什么 const 对象只能够调用const成员函数呢?,其实是这样的。由于对象本身通过 const 修饰,那么指向这个对象的指针也是指向const对象的const指针了。换句话说,指向这个对象的this指针是指向const对象的const指针。一般成员函数要求的this指针为:指向对象的const指针。所以此处发生了参数不匹配,无法进行调用。而 const 成员函数要求的this指针,恰恰是 指向const对象的const指针。所以依然能够调用。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11