- 项目介绍
- const那些事
- const的含义
- const作用
- const对象的访问范围
- const与指针
- const在函数中的使用
- const在类中的使用
这是笔者自己阅读C++那些事的过程中的笔记整理。该项目是一个适合初学者从入门到进阶的C++仓库。这里笔者和大家分享自己的阅读过程。希望大家在C++的学习过程中能够找到自己的乐趣。
const那些事主要介绍类型修饰符const在C++中的各种使用方式,和使用过程中需要注意的要点。
const的含义常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不可更新的。
const作用- 定义常量,如const int n = 100;定义常量时必须进行初始化,同时常量在定义之后不可更改!
- 类型检查, const常量具有类型,编译器可以进行安全检查,这也是#define宏定义常量无法做到的
- 可以防止修改,如void func(const int n){ n++; //error }
- 可以减少内存消耗,节省空间,避免不必要的内存分配,const定义常量从汇编角度来看,只给出对对应的内存地址,所以const定义的常量在程序运行过程中只有一份拷贝。
const对象默认为文件局部变量,非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定为extern。
//file1.cpp int ext; //extern_file.cpp extern const int EXT = 10; //file2.cpp #includeconst与指针extern int ext; extern const int EXT; int main() { std::cout << ext << std::endl; //0 std::cout << EXT << std::endl; //10 }
const和指针同时使用时,用如下四种方式:
const char * a; //指向const对象的指针即指向常量的指针 char const * a; //同上 char * const a; //指向类型对象的const指针。或者说常指针、const指针 const char * const a;//指向常量的常指针
小结:如果const位于*左侧,则const就是用来修饰指针指向的变量,即指针指向为常量,指针指向的内容不可更改;如果const位于*右侧,const就是修饰该指针本身,指针指向的地址不可更改,但是内容可以更改。
具体使用:
(1) 指向常量的指针
const int *ptr; *ptr = 10; //error const int p = 10; ptr = &p; //ok int* ptr2 = &p; //error
但是需要注意的一点是:允许把非const对象的地址赋值给指向const对象的指针
const int *ptr; int val = 3; ptr = &val; //ok *ptr = 4; //error val = 5; //ok
我们不能通过ptr修改val的值,但是可以通过其他方式修改val的值,同时ptr中的内容改变。
(2) 常指针
const指针必须进行初始化,且const指针指向的地址不能修改,但内容可以修改。
#includeusing namespace std; int main() { int num = 0; int* const ptr = # int* t = # *t = 1; cout << *ptr << endl; //1 *ptr = 2; cout << *ptr << endl; //2 int num1 = 10; ptr = &num1; //error }
(3) 指向常量的常指针
上面两种方式的结合:
const int a = 1; const int b = 2; const int* const ptr = &a; *ptr = 3; //error ptr = &b; //error
既不可以更改内容,又不可以更改指向地址。
const在函数中的使用- const修饰函数返回值
(1) const int 本身无意义,参数需要返回本身赋值给其他变量。
const int func1();
(2) const int* 指针指向的内容不可更改。
const int* func2();
(3)int *const 指针本身不可更改
int *const func3();
- const修饰函数参数
void func(const int var); // 传递过来的参数不可变 void func(int *const var); // 指针本身不可变
参数在函数内部不可更改,无意义。
void StringCopy(char *dst, const char *src);
参数指向的内容不可更改,防止在函数内部对src的更改,当函数体内的语句试图改动src的内容是,编译器将指出错误。
void func(const A &a)
比较常用的方式,参数为引用,在增加效率的同时,防止了函数体内部对参数的修改。
const在类中的使用void func(A a) 和 void func(A& a)的区别:
void func(A a)会在函数体内部生成A类型的临时对象用来复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
void func(A &a)提高效率,“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。
在此基础上,使用const修饰符,即可防止函数体内部对参数的修改。
在一个类中,任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改
数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。使用const关
字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格 *** 作常量或常对象,没有使用const关键字
明的成员函数不能用来 *** 作常对象。
- 类中的const成员变量必须通过初始化列表进行初始化。
//Object.h class Object { public: Object(int i); const int num; }; //Object.cpp #include "Object.h" Object::Object(int i) : num(i) { }
- const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。
//Object.h class Object { public: Object(int i); const int num; void doSomeThing(); void doSomeThingConst() const; }; //Object.cpp #include "Object.h" #includeObject::Object(int i) : num(i) { } void Object::doSomeThing() { std::cout << "do " << num << std::endl; } void Object::doSomeThingConst() const { std::cout << "do const " << num << std::endl; } //main.cpp #include "Object.h" int main() { Object a(1); const Object b(2); a.doSomeThing(); a.doSomeThingConst(); //b.doSomeThing(); //error b.doSomeThingConst(); }
输出:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)