C++技能系列 ( 2 ) - const的几种使用【详解】

这篇具有很好参考价值的文章主要介绍了C++技能系列 ( 2 ) - const的几种使用【详解】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

C++高性能优化编程系列
深入理解软件架构设计系列
高级C++并发线程编程
C++技能系列

期待你的关注哦!!!
C++技能系列 ( 2 ) - const的几种使用【详解】

生活就是上帝发给你的一张手牌,无论多烂,你都得拿着。
Life is god give you a hand, no matter how bad, you have to take.

一、声明带const

1、const int a

(1)表示常量a,不能改变a的值

//不能改变p的值
const char p = 'f';

2、const int &a

(1)表示常量引用,a代表的内容不能修改

int i = 100const int &a = i; //表示a所代表的内容不能被修改
const int &b = 156;  //可以,字面值初始化常量引用
int &c = 156; //错误
b = 157; //错误,b看成常量,值不能修改

3、const char *p & char const *p

(1)'char const *p;'等价于'const char *p;'
(2)表示常量指针(p所指向的内容不能通过p来修改):

char str[] = "I Love China";
char *p;
p = str;
*p = 'Y';
p++; //p可以指向不同的位置,只要这些位置的内存归我们管即可

如果将p的定义修改为:

const char *p; //表示常量指针(p所指向的内容不能通过p来修改)
*p = 'Y'; //错误

当然,通过str修改内容则没有问题:

str[0] = 'Y';

4、char * const p

(1)表示指针常量(p不可以指向其他内容):

看如下范例:

char str[] = "I Love China";
char * const p = str;  //定义的时候必须初始化
p++;   //这里不可以,p指向一个内容后,不可以指向其他内容(p不可以指向不同目标)
*p = 'Y';  //但可以修改指向的目标的内容

5、const char * const p & char const * const p

(1)'const char * const p;'等价于'char const * const p;'
(2)表示p的指向不能改变,p指向的内容也不能通过p来改变。

二、函数形参带const

1、函数形参带const的 - 使用

struct student {int num};
void fs(student &stu){
	stu.num = 1010;
}
student abc;
abc.num = 100;
fs(abc);
std::cout << abc.num << std::endl; //1010

上面这段代码,可以注意到,在fs()函数中可以修改stu里的num成员,修改后,该值会被带回到主调函数中,也就是说,fs()函数中对形参stu的修改实际就是对实参abc的修改,因为这里形参采用的是引用类型。

如果不希望在函数fs中修改形参stu里的值,建议形参最好使用常量引用的习惯。

void fs(const student &stu){
	stu.num = 1010;  //这句就错误了,不能修改stu中的内容
}

再继续看范例:

void fs(const int i){ //实参可以是正常的int,形参可以使用const int接,这都没问题
	i = 100;   //这也不行,不能给常量赋值
}

2、函数形参带const的 - 好处

(1)可以防止无意中修改了形参值导致实参值被无意中修改掉。
(2)实参类型可以更加灵活。

struct student {int num};
void fs(student &stu){
	
}
student abc;
abc.num = 100;
const student& def = abc;
fs(def);//错误,因为def类型是const&,而函数fs的形参不带const
std::cout << abc.num << std::endl; //1010

如果改成:

void fs(const student &stu){
	
}

可以看到const student &stu这种类型的形参可以接受的实参类型更多样化,可以接收普通的引用作为实参,也可以接收常量引用作为实参。

再继续看看如下范例:

void func2(int &a);//定义函数func2()
func2(156);//不可以,必须传递进去一个变量

修改后:

void func2(const int &a);//定义函数func2()
func2(156);//可以,可以船进去一个常量

三、成员函数末尾带const

成员函数末尾加const起什么作用呢?表示该成员函数不会修改该对象里面的任何成员变量的值。

这种在末尾加了一个const的成员函数也称常量成员函数。

class Persion{
public:
	void Get() const{
		a_ += 10;   //错误,常量成员函数不可以修改成员变量的值
	}
	void Add(int x){
		a_ = a_ - x ;
	}
private:
	int a_;
}

从上面的代码看,如果在Get的成员函数中修改成员变量a_的值,是不被允许的。

看看如下范例:

//	定义const对象,这种对象有限制
const Persion per;
//	不可以,Add成员函数是非const的,只能被非const的对象调用
per.Add(14);
// 可以因为Get()的成员函数是const
per.Get();
Persion per2;
//Get是const成员函数,则不管是cosnt对象还是非const对象都可以调用const员函数
//而非const得成员函数不能被const对象调用,只能被非const对象调用
per2.Add();

总结一下:

(1)const成员函数,则不管是cosnt对象还是非const对象都可以调用const员函数。
(2)而非const得成员函数不能被const对象调用,只能被非const对象调用。
(3)普通函数(非成员函数)末尾是不能加const, 编译都无法通过。

四、const的克星mutable

mutable,翻译成中文不稳定的、容易改变的意思。与const正好是反义词。而且mutable的引入也正是为了突破const的限制。

刚刚已经看到,在末尾有const修饰的成员函数中,是不允许修改成员变量值的。那在设计类成员变量的时候,假如确实遇到了需要在const结尾的成员函数中希望修改成员变量值的需求,怎么办呢?

也许有人会说,那就把函数末尾的const去掉,变成一个非const的成员函数。那就会引入一个新问题,如果这个成员函数从const变成一个非const的了,那么就不能被const对象调用。

所以,引入了mutable修饰符(关键字)来修饰一个成员变量。一个成员变量一旦被mutable所修饰,就表示这个成员变量永远处于可变的状态,即使在以const结尾的成员函数中。

看如下范例:

class Persion{
public:
	void Get() const{
		a_ += 10;  //可以修改成员变量a_了
	}
	void Add(int x){
		a_ = a_ - x ;
	}
private:
	mutable int a_;
}

五、小结

开发中经常使用,面试中也是经常被问的,所以谨记于心。文章来源地址https://www.toymoban.com/news/detail-505247.html

到了这里,关于C++技能系列 ( 2 ) - const的几种使用【详解】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot系列】接收前端参数的几种方式

    前言 在现代Web开发中,前后端分离的架构已经成为主流。前端负责展示页面和用户交互,而后端则负责处理业务逻辑和数据存储。在这种架构下,前端需要将用户输入的数据发送给后端进行处理。而Spring Boot作为一种快速开发框架,提供了多种方式来接收前端数据。 本文将介

    2024年02月05日
    浏览(34)
  • 【SpringBoot系列】实现跨域的几种方式

    前言 在Web开发中,跨域是一个常见的问题。由于浏览器的同源策略,一个Web应用程序只能访问与其自身同源(即,相同协议、主机和端口)的资源。 这种策略的存在是为了保护用户的安全,防止恶意网站读取或修改用户的数据。 然而,现代Web应用程序经常需要访问不同源的

    2024年02月01日
    浏览(40)
  • C++中const char*、char const*和char * const的区别详解

       1、const char* p: 2、char const*:  等价于const char*; 用法如上,这里不过多解释  3、char * const: 4、const char * const p = str 等价于 char const * const p=str     p的指向不能改变,p指向的内容也不能被改变; 5、 补充:

    2024年02月04日
    浏览(29)
  • 【SpringBoot系列】读取yml文件的几种方式

    前言 在Spring Boot开发中,配置文件是非常重要的一部分,而yml文件作为一种常用的配置文件格式,被广泛应用于Spring Boot项目中。Spring Boot提供了多种方式来读取yml文件中的属性值,开发者可以根据具体的需求和场景选择合适的方式。本文将介绍Spring Boot读取yml文件的主要方式

    2024年02月05日
    浏览(31)
  • 重学C++系列之const与static关键字分析

            本篇幅讲解const与static,主要围绕在类的范围内叙述,包括作用和使用场景等。         1、const修饰的成员变量,成员变量初始化后不能再修改。         2、const修饰的成员函数,成员函数不可以修改成员变量,也不能间接修改。         3、static修饰的成员

    2024年02月15日
    浏览(38)
  • 【Mysql系列】mysql中删除数据的几种方法

    在MySQL数据库中,删除数据是一个常见的操作,它允许从表中移除不再需要的数据。在执行删除操作时,需要谨慎,以免误删重要数据。 以下是MySQL中删除数据的几种方法: DELETE语句 DROP TABLE语句 TRUNCATE TABLE 使用外键约束 DELETE语句是最常用的删除数据方法之一。它允许您根据

    2024年02月05日
    浏览(32)
  • C++实现回调函数的几种方式

    通常认为通过函数指针在其他地方调用函数的过程称为回调,被调用的函数称为回调函数,函数指针通过传参方式传递。 在C++的实际应用中,有很多实现回调函数的方式,不一定要传递函数指针才能实现回调,只要实现了回调的功能,都叫回调函数。 回调函数是和调用者在

    2024年02月16日
    浏览(32)
  • 【C++】const关键字的详解!!

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 const是永恒不

    2024年02月03日
    浏览(36)
  • c++初始化vector的几种方法

    在C++中,vector是一种动态数组,可以在运行时自由添加、删除元素。初始化vector是创建一个vector对象并为其分配内存空间的过程。以下是C++中初始化vector的几种方法: 默认构造函数 使用默认构造函数创建一个空的vector,如下所示: std::vectorint vec; // 创建空vector 这种方式可用

    2024年02月16日
    浏览(33)
  • C++中确保线程安全的几种方式

    在 C++ 中,可以使用以下几种方式来确保线程安全: 使用互斥量(mutex)来对共享资源进行保护。互斥量可以用来防止多个线程同时访问共享资源,从而避免数据竞争的问题。 使用读写锁(reader-writer lock)来对共享资源进行保护。读写锁允许多个读线程同时访问共享资源,但

    2023年04月17日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包