1.const修饰指针
const修饰指针有三种情况
const修饰指针 — 常量指针
const修饰常量 — 指针常量
const即修饰指针,又修饰常量
int main() {
int a = 10;
int b = 10;
//const修饰的是指针,指针指向可以改,指针指向的值不可以更改
const int * p1 = &a;
p1 = &b; //正确
//*p1 = 100; 报错
//const修饰的是常量,指针指向不可以改,指针指向的值可以更改
int * const p2 = &a;
//p2 = &b; //错误
*p2 = 100; //正确
//const既修饰指针又修饰常量
const int * const p3 = &a;
//p3 = &b; //错误
//*p3 = 100; //错误
system("pause");
return 0;
}
技巧:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量
2.const修饰变量
const int a=100;//a的值将无法更改
const变量和define宏定义变量的区别:const常量具有类型,编译器可以进行安全检查;#define宏定义没有数据类型,只是简单的字符串替换,不能进行安全检查。const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
3.const修饰函数
(1)const int
const int func1();
这个本身无意义,因为参数返回本身就是赋值给其他的变量!
(2)const int*
const int* func2();
指针指向的内容不变。
(3)int *const
int *const func2();
指针本身不可变。
const修饰函数参数
(1)参数指针所指内容为常量不可变
void StringCopy(char *dst, const char *src);
其中src 是输入参数,dst 是输出参数。给src加上const修饰后,如果函数体内的语句试图改动src的内容,编译器将指出错误。这就是加了const的作用之一。
(2)参数为引用,为了增加效率同时防止修改。
void func(const A &a)
对于非内部数据类型的参数而言,象void func(A a) 这样声明的函数注定效率比较低。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
为了提高效率,可以将函数声明改为void func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void func(A &a) 存在一个缺点:“引用传递”有可能改变参数a,这是我们不期望的。
解决这个问题很容易,加const修饰即可,因此函数最终成为 void func(const A &a)。
以此类推,是否应将void func(int x) 改写为void func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。
小结:对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void func(A a) 改为void func(const A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void func(int x) 不应该改为void func(const int &x)。
4.const修饰类和类的成员函数
- 类的成员函数后加const后我们称为这个函数为常函数
- 常函数内不可以修改成员属性
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数,非常对象可以访问任意的成员函数,包括const成员函数。
#include<iostream>
using namespace std;
class Apple
{
private:
int people[100];
public:
Apple(int i);
const int apple_number;
void take(int num) const;
int add(int num);
int add(int num) const;
int getCount() const;
};
Apple::Apple(int i):apple_number(i)
{
}
int Apple::add(int num){
take(num);
}
int Apple::add(int num) const{
take(num);
}
void Apple::take(int num) const
{
cout<<"take func "<<num<<endl;
}
int Apple::getCount() const
{
take(1);
// add(); //error
return apple_number;
}
int main(){
Apple a(2);
cout<<a.getCount()<<endl;
a.add(10);
const Apple b(3);
b.add(100);
return 0;
}
//编译结果
take func 1
2
take func 10
take func 100
reference:
1.C++那些事
2.C++基础入门