const修饰变量
//i是常量,不可变,用于替代C的宏定义 const int i=10;
const修饰指针的三种情况
1)const在*
前,此时是修饰量,指针指向的量不可变,不能用*p修改这个量;但指针自身可以变,可以指向其他地方。
int a=100; const int *p = &a; //或 int const *p = &a; *p = 5;//!!!!错误,不能通过这种途径改变量 a = 5; //可以 p = p+1;//可以,指针自身可以变
2)const在*
之后,修饰指针本身,指针不能变,但是指向的量可以变。
int a = 100; int * const p = &a; p++;//!!!错误,指针不能变 *p = 5;//可以
3)*
前后都有const修饰符号,当然是指针和指向的值都不能变
const int * const p = &a;
const修饰函数形参
1)const修饰说明该变量在函数内部不能(不会)被修改,当函数不修改传入的形参时,最好带上const;
2)如果函数运行时被传入的实际参数是const常量,则形参必须是const修饰的,如果实参是普通变量,形参是不是const都可以。所以,如果函数不改变形参,就在函数形参加上const;尤其是传引用的时候,因为能改变原来的值,编译器默认不加const的形参都会被改变,所以不允许你传入const的实参。
3)如果函数确实要改变参数内容,那就不要加const修饰了
4)回顾一点函数传参的知识,普通数据类型就传值就好,除非要修改内容,也可以选择传指针;C++数据类型,**结构,类都用传引用,**更快,不管是否修改内容,不修改就加上const修饰形参;
struct stud { int num; }; void func1(stud& A); //只能传入普通变量 void func2(const stud& A); //功能更强大,const和普通都可以传入 int main() { stud A; const stud B; func1(A);//可以 func1(B);//不可以,编译器默认func1()会修改变量 func2(A);//可以 func2(B);//可以 return 0; }
const在成员函数末尾
只会在成员函数末尾哈,普通非成员函数末尾不可能有const,它是为了告诉系统,此成员函数不会改变任何成员变量,常量成员函数。
class A { private: int num; public: void print() const; //声明和定义都带 } void A::print() const {cout<<num<<endl;}
这里拓展mutable修饰成员变量,即使在const成员函数里,也可以被改变。
const成员变量的初始化
因为const修饰是常量,则不能被赋值,所以只能在初始化列表中初始化,不能在构造函数中赋值。
即使不是const常量成员变量,能初始化列表
里初始化的就选择初始化列表,不要在构造函数内部再赋值,这是两个前后进行的过程,初始化列表更快,省去了默认初始化再赋值。
class A { private: const int a; const double b; public: A(); A(int aa, double bb); } A::A():a(0), b(0) {} A::A(int aa, double bb):a(aa), b(bb)//在函数括号后面:的后面,在{}之前,‘,’隔开 {} //而不能像下面这样 A::A(int aa, double bb) { a=aa; //这是赋值了 b=bb; }