const详解

const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。

修饰基本数据类型

2.1 const修饰一般常量及数组

int const a = 100;
const int a = 100; //与上面等价
int const arr [3] = {1,2,3};
const int arr [3] = {1,2,3};//与上面等价

限定这些变量作为常量,无法修改
image.png

2.2 const修饰指针(*)

2.2.1 常量指针

当为常量指针时,不可以通过修改所指向的变量的值,但是指针可以指向别的变量。

int a = 5;
const int *p =&a;
*p = 20;   //error  不可以通过修改所指向的变量的值

int b =20;
p = &b; //right  指针可以指向别的变量

2.2.2 指针常量

当为指针常量时,指针常量的值不可以修改,就是==不能指向别的变量==,但是==可以通过指针修改它所指向的变量的值。

int a = 5;
int *const p = &a;
*p = 20;     //right 可以修改所指向变量的值

int b = 10;
p = &b;      //error 不可以指向别的变量

2.2.3 总结

如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;

如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。

const修饰函数

const 在函数中根据修饰的位置分为三种:函数参数、函数返回值、成员函数。

const  int fun (const int a) const;

3.1 const修饰函数参数

修饰函数形参;函数体内不能修改形参a的值。

如果函数作为输出用,不论是什么数据类型,也不论采用指针传递还是引用传递,都不能加const 修饰,否则参数会失去输出功能。所以:const 只能修饰输入作用的参数

image.png

3.1.1 如果参数为指针

如果输入参数为指针,加上const之后就会起保护指针意外修改的作用。

void StringCopy(char* strDest, const char* strSource);

在这个函数定义中,我们的的参数strsource加上const修饰,就是为了防止strsource被修改。
实参中,指针会指向一段内存地址,调用函数之后,函数会产生一个临时指针变量,这个变量的地址与实参的地址不一样,但是这两个指针指向的内存是同一块。形参加上const 修饰之后,保护了这一块内存地址不被修改,如果刻意修改这一块内存,编译器会报错。

image.png

3.1.2 如果参数为引用

如果输入参数为引用,加上const 之后既起到了保护作用,也提高了程序效率。
我们前面用到的构造函数Stock::Stock(const string &co,long n,double pr)这里的const引用是因为如果我们string co,则函数需调用构造函数创建一个临时对象,如果用引用,则表示是实参的一个别名,不会产生临时对象,而const这里是为了防止修改对象。

3.2 const修饰函数返回值

修饰返回值,就是不能修改返回值

  • 对于函数来说,返回值如果是int类型的值,就算用const限定,但是函数调用结束会清楚栈,因此没有必要
  • 如果函数返回值是指针的话,我们加上限定符号,接收的变量也必须有限定符
const char * func();
const char* str = func();
  • 如果返回值是引用,也可以提高效率。但是一般返回引用的地方并不是很多,一般会出现在类的赋值函数中。而且,用const 修饰返回值为引用类型的更少。一般来说不常用。

3.3 const修饰成员函数

const 修饰的成员函数为了保护成员变量,要求const 函数不能修改成员变量,否则编译会报错。 函数体内不能修改成员变量的值,只有成员函数才可以在后面加const,普通函数后加const无意义。

class Stock
{
private:

	std::string company;
	long share;
	double share_val;
	double total_val;
	void set_tot() { total_val = share_val * share; }
public:
	Stock();
	~Stock();
	Stock(const std::string& co, long n, double pr);
	void buy(long num, double price);
	void sell(long num, double price);
	void update(double price);
	void show() const;//const
};

image.png

const函数

  1. const 对象只能访问const 成员函数,非const 的对象可以访问任何成员函数,包括const 成员函数。
  2. 如果函数名、参数、返回值都相同的const成员函数和非const成员函数是可以构成重载,那么const对象调用const成员函数,非const对象默认调用非const的成员函数。
  3. const成员函数可以访问所有成员变量,但是只能访问const的成员函数。
  4. 非const成员函数,可以访问任何成员,包括const成员成员函数。
    const成员函数不能修改任何的成员变量,除非变量用mutable修饰。

使用const的好处

  1. 可定义常量
    防止意外修改造成的错误
  2. 便于进行类型检查
    const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。
  3. 为函数重载提供了一个参考
    const修饰的函数可以看作是对同名函数的重载。
  4. 可以节省空间,避免不必要的内存分配
    const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象宏一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而宏定义的常量在内存中有若干个拷贝。
  5. 提高了效率
    编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期的常量,没有了存储与读内存的操作,使得它的效率也很高。
    所以我们在平时使用参数的时候,对于没有修改需求的变量或者参数 应该用const保护。

网站标题:CV鼻祖洋芋

原创文章,作者:locus,如若转载,请注明出处:https://blog.cvpotato.cn/forward-code/c/202/

本博客所发布的内容,部分为原创文章,转载注明来源,网络转载文章如有侵权请联系站长!

(0)
上一篇 6天前
下一篇 6天前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注