当前位置: 首页 > article >正文

C++系列-const所有用法总结

const用法总结

  • const修饰变量
    • const修饰普通变量
    • const修饰指针变量
      • 常量指针
      • 指针常量
      • 常量指针常量
    • const修饰引用
  • const修饰函数形参
    • 参数是普通的值传递
    • 参数类型是引用
  • const修饰函数返回值
    • 值传递方式返回
    • 指针方式返回
    • 常量引用方式返回
  • const修饰成员函数
    • const 修饰在函数名后面
  • 常对象


春日 - 朱熹
胜日寻芳泗水滨,无边光景一时新。
等闲识得东风面,万紫千红总是春。


const 是 constant 的缩写,本意是不变的,不易改变的意思。

const修饰变量

const修饰普通变量

  • 定义常量
  • 一般常量变量名用大写
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;

void main()
{
	// MAX_VALUE = 50;		// 常量的值不可被修改,定义时就确定好了
	system("pause");
}

const修饰指针变量

常量指针

  • const int *p; const:常量 , * 指针,故为常量指针
  • const修饰的是*p,所以,*p不能修改,即指针指向的内容不能通过指针修改。 *p=xx 是错误的,但是指针本身可以修改,即指针可以指向其它地址。 p = &a 是正确的。
code:
#include <iostream>
using namespace std;
int main()
{
	int a = 10;
	int b = 20;
	const int* p = &a;
	cout << "a的地址: " << &a << endl;
	cout << "p的值: " << p << endl;
	// *p = 20;		// 错误,const修饰的是*p,则*p的值不可修改,即p指向的内容不可改
	p = &b;			// p的指向是可以修改的
	cout << "b的地址: " << &b << endl;
	cout << "p的值: " << p << endl;
	system("pause");
	return 0;
}

result:
a的地址: 00000001930FF5C4
p的值: 00000001930FF5C4
b的地址: 00000001930FF5E4
p的值: 00000001930FF5E4

指针常量

  • int * const p; * 指针, const 常量,故为指针常量
  • const修饰的是p,所以p不能修改,即指针的指向不能修改,不能指向其它的地址,但是指针指向的地址中的内容是可以通过*p=xx修改的。
code:
#include <iostream>
using namespace std;
int main()
{
	int a = 10;
	int b = 20;
	int* const p = &a;	// 指针常量,const修饰p,则p的指向不可修改
	cout << "a的地址: " << &a << endl;
	cout << "p的值: " << p << endl;
	// p = &b;		// 错误,p的指向不可修改
	*p = 20;		// ,const修饰的是*p,则*p的值不可修改,即p指向的内容不可改
	//p = &b;			// p的指向是不可以修改的
	cout << "a的值: " <<  a << endl;
	system("pause");
	return 0;
}

result:
a的地址: 000000AB945FF994
p的值: 000000AB945FF994
a的值: 20

常量指针常量

  • const int * const p:const 修饰了*,const又修饰了p,所以指针本身和其指向的内容都是常量,都不能修改。*p=xx错误,p=xx错误。

const修饰引用

  • 常量引用只是对引用可参与的操作做出了限定,对于引用的对象本身是不是常量未作限定,所以对象本身还是可以修改的。
code:
#include<iostream>
using namespace std;

int main(void)
{
	int i = 1;
	const int& cj = i;  // const引用普通变量
	cout << "------ 1 ------, " << cj << endl;
	//cj=2;				// 错误cj被const修饰,不可以改变,无法通过引用改变它引用的内容
	i = 3;				// 正确,i可以被修改,cj也随之被更改
	cout << "------ 2 ------, " << cj << endl;
	system("pause");
	return 0;
}

result:
------ 1 ------, 1
------ 2 ------, 3

const修饰函数形参

  • 形参的值在函数中是可以改变的,如果形参是个指针或者引用,则形参在改变时,直接改变的就是实参。
  • 防止参数在函数中被意外修改时,可以在形参前加const。
  • 写函数的时候尽量使用常量引用,不会产生副本,且可读性强。
  • 当函数的参数作为输出时,不应该const修饰,要不然你没法修改。

参数是普通的值传递

  • 普通的值传递,形参即使改变,也不会影响实参的结果,所以加不加const都无所谓。
code:
#include <iostream>  
#include <string>  
using namespace std;
void print_str(const string s)		// 值传递,形参和实参并不是同一空间,
// 这里加不加const都不会影响实参的值
{
	//s = "jh"; // 会报错,s无法修改
	cout << s << endl;
}
int main()
{
	string str1 = "hello world";
	print_str(str1);
	system("pause");
	return 0;
}

result:
hello world

参数类型是引用

  • 形参和实参指向的是同一空间,则限值了形参为const,形参无法改变,从而实参也不会改变。
#include<iostream>
using namespace std;

void func(const int &a)		// 在调用函数的时候,t1传给a,则a为t1的引用,而const修饰了a,那么a是无法改变的,t1也就无法改变
{
	cout << a << endl;
	//++a;  //是错误的,a 不能被改变
}

int main(void)
{
	int t1 = 10;
	func(t1);
	system("pause");
	return 0;
}

const修饰函数返回值

const修饰函数返回值,表示返回值不可被改变。

值传递方式返回

  • 如果函数返回值采用值传递方式,返即返回的是一个副本。修改这个副本并不会影响原始值,加不加const都一样。
// 以下效果一样
const int func1(int a);
int func1(int a);

指针方式返回

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针;

const char * GetString(void); // 返回值是常量指针

//如下语句将出现编译错误:
//char *str = GetString();

//正确的用法是
const char *str = GetString(); // 返回是常量指针,则只能赋值给常量指针


常量引用方式返回

用 const 修饰返回的引用,保护引用的内容不被修改。

code:
#include <iostream>
using namespace std;

class Person {
public:
	int& get_age() 
	{
		cout << "m_age的地址: " << & m_age << endl;
		return m_age;
	}
	const int& get_age_const()	// const int &,则无法通过返回的引用改变m_age的值
	{
		return m_age;
	}
	void show_age() 
	{
		cout << "age: " << m_age << endl;
	}
private:
	int m_age = 0;
};

int main()
{
	Person p1;
	p1.show_age();
	cout << "p1.get_age()的地址: " << &p1.get_age() << endl;
	p1.get_age() = 5;	// p1.get_age()的返回值是m_age的引用,
	//这句话就是改变m_age的值,会修改成员变量的值
	p1.show_age();

	//p1.get_age_const() = 8;	// 编译器会报错,因为p1.get_age_const()返回的是
	// const int&, 常量引用,无法通过引用改变变量的值。
	//p1.show_age();
	system("pause");
	return 0;
}

result:
age: 0
m_age的地址: 0000002D1F3BF734
p1.get_age()的地址: 0000002D1F3BF734
m_age的地址: 0000002D1F3BF734
age: 5

const修饰成员函数

  • 成员函数后加const,称为常函数。
  • 常函数内不可以修改成员属性。
  • 成员属性在声明时,如果前面加mutable,在常函数仍然可以修改。

const 修饰在函数名后面

  • 其本质是const修饰的是this指针,this指针的本质是指针常量,即指针的指向(其地址)不可修改,在函数后加const后,是让this指针指向的内容也不可修改。
code:
	#include <iostream>
	using namespace std;
	class Horse
	{
	public:
		int age = 3;
		mutable string color = "white";
		//this 指针是一个指针常量, Horse * const this, 它指向的地址不可以修改, const Horse * const this, 则表示其空间的内容也不能修改
		void show_age() const		//常函数,const其实是用来修饰this指针的,表示this指向的内存空间的内容也不可以修改
		{
			//age = 5;				// 常函数中不能修改普通成员变量
			color = "black";		// 当成员变量被mutable修饰后,常函数中可以修改
			cout << "it is " << age << endl;
		}
	};
	
	int main()
	{
		Horse horse1;
		horse1.show_age();
		system("pause");
		return 0;
	}
result:
	it is 3

常对象

  • 在声明对象前加const,常对象,常对象的内容不可以修改。
  • 常对象只能调用常函数。
  • 常对象可以修改mutable修饰的成员变量。
code:
	#include <iostream>
	using namespace std;
	class Horse
	{
	public:
		int age = 3;
		mutable string color = "white";
		//this 指针是一个指针常量, Horse * const this, 它指向的地址不可以修改, const Horse * const this, 则表示其空间的内容也不能修改
		void show_info() const		//常函数,const其实是用来修饰this指针的,表示this指向的内存空间的内容也不可以修改
		{
			//age = 5;				// 常函数中不能修改普通成员变量
			color = "black";		// 当成员变量被mutable修饰后,常函数中可以修改
			cout << "it is " << age << endl;
		}
		void show_info_1()
		{
			//age = 5;				
			color = "black";
			cout << "it is " << age << endl;
		}
	};
	
	int main()
	{
		Horse horse1;
		horse1.show_info();
		const Horse horse2;			// 常对象内的内容不可以修改
		//horse2.age = 5;			// 常对象不能修改普通的成员变量
		horse2.color = "brown";		// 常对象可以修改mutable修饰的成员变量
		cout << horse2.age << endl;
		cout << horse2.color << endl;
		horse2.show_info();
		//horse2.show_info_1();		// 常对象不能调用普通的成员函数,因为普通成员函数可以修改成员变量的值,而常对象对应的成员变量是不可以修改的,冲突。
		system("pause");
		return 0;
	}
result:
	it is 3
	3
	brown
	it is 3

http://www.kler.cn/a/289057.html

相关文章:

  • 论文翻译 | The Capacity for Moral Self-Correction in Large Language Models
  • Linux——GPIO输入输出裸机实验
  • vscode远程连接服务器并启用tmux挂载进程
  • 大模型时代,呼叫中心部门如何自建一套大模型在线客服?
  • 排序算法 - 冒泡
  • 【vue2.0入门】vue基本语法
  • HALCON 错误代码 #7709
  • python-简单的dos攻击
  • 第十四章 rust集合库介绍
  • Mybatis【分页插件,缓存,一级缓存,二级缓存,常见缓存面试题】
  • 【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (二)
  • 免费升级https访问
  • Vue3 reactive和ref
  • Chapter 07 watch侦听器
  • 【Next】1. 初识服务端渲染
  • OpenHarmony如何切换横竖屏?
  • 科研绘图系列:R语言富集火山图和通路图(volcano plot pathway)
  • 实现流程化办公,可专注于开源可视化报表设计器!
  • F12抓包01:启动、面板功能介绍、语言设置、前端样式调试
  • 【#第三期实战营闯关作业 ## MindSearch在 Hugging FaceSpace的部署】
  • 缓存解决方案。Redis 和 Amazon ElastiCache 比较
  • lit-llama代码解析
  • 【C++ 面试 - STL】每日 3 题(五)
  • 解读GaussianTalker:利用音频驱动的基于3D高斯点染技术的实时高保真讲话头像合成
  • Idea_服务器自动化部署_傻瓜式教程
  • MySQL中的分组统计