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

相关文章

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S