const修饰类成员和类对象、const修饰成员函数构成重载、可变数据成员mutable、

2024-03-01 22:08

本文主要是介绍const修饰类成员和类对象、const修饰成员函数构成重载、可变数据成员mutable、,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其他文章:C++中const成员函数和非const成员函数的重载_梦心之魂的博客-CSDN博客

const修饰数据成员、成员函数

1.const 修饰数据成员:初始化位置可以在参数列表中,新版本也可以在声明位置直接初始化,被const修饰的数据成员,不能被修改

2. const 修饰成员函数:const位置在函数声明之后、实现体之前如果分.h和.cpp的话,要求在定义和声明处都要有const修饰,是从函数的层面,不修改数据。

意义:const函数承诺,不会修改数据成员(无论数据成员有没有const),能访问const 和非const数据成员,但不能修改数据成员,const数据成员只能访问const成员函数因为只有const函数才能保证不会修改
作用:提供对于const对象调用时的支持

#include "stdafx.h"
#include <iostream>
using namespace std;class A
{
public:A(int v = 0):val(v){}//const 只能放在函数后面 因为 const void 和 void const //都是修饰返回类型void的void dis() const{cout << val << endl;//val = 200; const的数据成员一定改不了//x=200; const函数承诺不会修改数据成员(无论加不加const)//print(); 也不可以间接去修改print(); //可以访问const成员函数}void dis(){cout << "void dis() " << endl;}void print()       //this指针的类型是A*{x = 100;y = 200;}void print() const //this指针的类型是const A*{cout << "void print() const" << endl;}
private:const int val; //新版本修饰数据成员可以在这初始化int x, y;
};int _tmain(int argc, _TCHAR* argv[])
{A a(5);        //非const类对象a.dis();       //有非const的成员函数优先 其次调用const成员函数const A a1(5); //const类对象a1.print();a1.dis();      //const对象只能调用const函数return 0;
}

const修饰成员函数与普通成员函数构成重载

在函数重载中有一种特殊的函数重载方法,那就是const修饰成员函数的重载,对于const修饰的类对象,是从对象的层面,不修改数据,只能调用const成员函数。

const对象与const成员函数的调用规则

1.const对象 只能调用const成员函数
2.非const成员对象,优先调用非const成员函数,若没有,则可调用const成员函数

原因:按照函数重载的定义,函数名相同而形参表有本质不同的函数称为重载。在类中,由于隐含的this形参的存在const版本的成员函数使得作为形参的this指针的类型变为指向const对象的指针,而非const版本的使得作为形参的this指针就是正常版本的指针。此处是发生重载的本质。重载函数在最佳匹配过程中,对于const对象调用的就选取const版本的成员函数,而普通的对象调用就选取非const版本的成员函数。(注:this指针是一个const指针地址不能改,但能改变其指向的对象或者变量)

const修饰的成员函数返回类型为*或者&时,最好再使用const来修饰返回值

我们已经知道const修饰成员函数的作用之一就是保证不会修改类中的数据成员,那么如果这个函数将数据成员的*和&类型作为返回值时,我们却可以间接的修改其数据成员,大多情况下,这与我们的期望并不相符,所以在返回类型为引用或指针的const成员函数中,最好再使用const来修改其返回值。

例如String类中我们为它提供一个下标操作符([ ])以读写指定位置的字符,只要了解过C++的操作符重载的语法,很快就可以写出下面这个[]操作符重载函数

char& operator[](int posion)    // function_1{return data[posion];};

注意,这里该函数的返回值为一个引用,否则str[0] = 'c'这样的语句就会不合法,因为str[0]将是一个左值。那么,是否提供这样一个function_1就足够了呢?看下面这段代码:

const String str= "She";
char c = str[0];  // 错误!编译提示:error C2678: 二进制“[” : 没有找到接受“const String”类型的左操作数的运算符(或没有可接受的转换)

很显然,我们必须还要为const String提供一个const版本的opeartor[],因为const修饰的类对象只能调用const修饰的成员函数。

char& operator[](int posion) const
{return data[posion];
}

这样,当使用const的String对象使用[]操作符时,便会调用该const的重载版本。但是,这样就OK了嘛?虽然上面的那段代码没有问题了,但是其中却隐藏了一个陷阱,看如下代码:

const String str = "She";
str[0] = 'T';

上面这段代码可以编译,运行通过,str变为了"The"!而str声明为const的!!现在,你应该知道了,对于const的该操作符重载函数其返回值也应该是const的,否则就会出现可以通过其修改const对象的漏洞。为了给String提供一个[]操作符来读写指定位置的字符,需要提供如下两个函数,以分别对非const String对象和const String对象提供支持

char& operator[](int posion)
{return data[posion];
};const char& operator[](int posion) const
{return data[posion];
}

可变数据成员mutable

有时会发生这样一种情况,我们希望能修改类的某个数据成员,即使是在一个const成员函数内,可以通过在变量的声明加入mutable关键字做到这一点,因此它可以使const成员函数可以改变一个可变成员的值,一个可变数据成员永远不会是const

class Screen
{
public:void some_member() const;
private:mutable size_t access_ctr;  //即使在一个const对象内也能被修改
};void Screen::some_member() const
{++access_ctr;  //保存一个计数值,用于记录成员函数被调用的次数
}

这篇关于const修饰类成员和类对象、const修饰成员函数构成重载、可变数据成员mutable、的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/763980

相关文章

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

使用SpringBoot+InfluxDB实现高效数据存储与查询

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目... 目录1、项目介绍2、 InfluxDB 介绍3、Spring Boot 配置 InfluxDB4、I

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

python中update()函数的用法和一些例子

《python中update()函数的用法和一些例子》update()方法是字典对象的方法,用于将一个字典中的键值对更新到另一个字典中,:本文主要介绍python中update()函数的用法和一些... 目录前言用法注意事项示例示例 1: 使用另一个字典来更新示例 2: 使用可迭代对象来更新示例 3: 使用

Python实现数据可视化图表生成(适合新手入门)

《Python实现数据可视化图表生成(适合新手入门)》在数据科学和数据分析的新时代,高效、直观的数据可视化工具显得尤为重要,下面:本文主要介绍Python实现数据可视化图表生成的相关资料,文中通过... 目录前言为什么需要数据可视化准备工作基本图表绘制折线图柱状图散点图使用Seaborn创建高级图表箱线图热

MySQL数据脱敏的实现方法

《MySQL数据脱敏的实现方法》本文主要介绍了MySQL数据脱敏的实现方法,包括字符替换、加密等方法,通过工具类和数据库服务整合,确保敏感信息在查询结果中被掩码处理,感兴趣的可以了解一下... 目录一. 数据脱敏的方法二. 字符替换脱敏1. 创建数据脱敏工具类三. 整合到数据库操作1. 创建服务类进行数据库