深入探索C++类的const成员函数

2023-10-30

深入探索C++类的const成员函数

const 成员变量的用法和普通 const 变量的用法相似,只需要在声明时加上 const 关键字。初始化 const 成员变量只有一种方法,就是通过构造函数的初始化列表。

const 成员函数可以使用类中的所有成员变量,但是不能修改它们的值,这种措施主要还是为了保护数据而设置的。const 成员函数也称为常成员函数。

我们通常将 get 函数设置为常成员函数。读取成员变量的函数的名字通常以get开头,后跟成员变量的名字,所以通常将它们称为 get 函数。

(1)const 成员函数把 const 关键字放在函数的形参列表和函数体之间。比如

class A
{
    void f() const {}
    const int g()
    {
        return 2;
    }
};

其中函数 f 是 const 成员函数,函数 g 只是一个返回类型为 const int 的函数。

(2)在类体外定义 const 成员函数时也必须同时指定 const 关键字。比如

class A
{
    void f() const;
};

在类体外定义函数 f 的形式为

void A::f() const f{...};

(3)在 const 成员函数体内,数据成员相当于被 const 修饰,即 const 成员函数不能修改类的数据成员,但非类的数据成员则可以修改。

比如

class A
{
    int a;
    void f(int b) const
    {
        int c;
        b = l;
        c = 2;
        a = l;
    }
};

其中 a = 1; 是错误的,其他都是正确的。因为 b 和 c 不是类的数据成员。再比如

class A
{
    int a;
    void f() const 
    {
        int* p = &a;
        const int *pl = &a;
    }
};

其中 const int *pl = &a; 是正确的,int* p = &a; 是错误的,因为指向非 const 的指针不能指向 const 常量,在 const 成员函数内部相当于被 const 修饰。

(4)在 const 成员函数体内,成员指针也相当于被 const 修饰,但 const 是修饰的指针本身也就是指针成员相当于 * const p 。因此在

const 成员函数体内能修改指针成员所指向的对象的值但不能改变指针成员本身的值,或者说指针成员是常量,但指向的值不是常量。比如

class A
{
public:
    int a;
    int *p;
    void f() const
    {
        int b = l;
        *p = 3;
        p = &b;
    }
};

其中 p = &b; 是错误的。注意:需要加一个构造函数初始化指针 p。

(5)const 成员函数可以与具有相同参数表的非 const 成员函数形成重载,在调用时,非 const 对象将调用非 const 成员函数,而 const 对象则只能调用 const 成员函数。比如 class A{void f(){}; void f() const{} };,其中的两个函数 f 是重载关系,而非重定义;再比如const A ma; A mb;,则 ma.f() 将调用 const 成员函数,mb.f() 将调用非 const 成员函数。

(6)const 成员函数不能调用非 const 成员函数。因为在const 成员函数内,调用类的成员时需要通过隐藏的 this 指针,而 const 成员函数的 this 指针类型为 const 类名 *const ,即既不能改变 this 指针本身的值,也不能改变 this 指针所指向的对象,因为无法保证非 const 成员函数不改变数据成员的值,所以const成员函数不能调用非 const 成员函数。

(7)注意:若使用强制转换去掉 this 的 const 性质,const 成员函数就可以调用非 const 成员函数了;同理,也可以在 const 成员函数内改变数据成员的值。比如

class A
{
public:
    int a;
    void g() {}
    void f() const
    {
        ((A* const)this)->g();
        ((A* const)this)->a=4;
    }
};

正确,其中 ((A* const)this) 表示把 this 指针强制转换为 A* const ,即强制转换去掉了最前面的 const。

(8)注意:非成员函数不能把 const 关键字放在小括号之后,比如 void f()const{}; 是错误的。

例子

class Student{
public:
    Student(char *name, int age, float score);
    void show();
    //声明常成员函数
    char *getname() const;
    int getage() const;
    float getscore() const;
private:
    char *m_name;
    int m_age;
    float m_score;
};

Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
void Student::show(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
}
//定义常成员函数
char * Student::getname() const{
    return m_name;
}
int Student::getage() const{
    return m_age;
}
float Student::getscore() const{
    return m_score;
}

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入探索C++类的const成员函数 的相关文章

随机推荐

  • QTCreator在Ubuntu安装及运行程序报错解决

    1 QT Creator安装 软件包下载 可以进入官网下载或者使用wget命令下载 个人使用wget命令安装如下 sudo wget http download qt io archive qt 5 12 5 12 9 qt opensou
  • VScode修改行间距

    在我们编码的过程中 由于显示字体和显示器的不同 会需要调整行间距 在vscode默认的选项中没有看到设定行间距的选项 不过 可以手动修改配置档达到目的 1 打开设置 2 打开配置档 手动进行设定 3 在选项中添加 editor lineHe
  • Kafka中Producer源码解读

    Producer源码解读 在 Kafka 中 我们把产生消息的一方称为 Producer 即 生产者 它是 Kafka 的核心组件之一 也是消息的来源所在 它的主要功能是将客户端的请求打包封装发送到 kafka 集群的某个 Topic 的某
  • Qt极简贪吃蛇实现

    持续修正更新该项目 环境 Qt 4 8 Qt5环境也可使用 全部文件传送门 部分重要模块代码 include snakegame h include ui snakegame h SnakeGame SnakeGame QWidget pa
  • 连接SQL Server 数据库

    目录 一 启动 SQL Server Management Studio 1 点击 SQL Server Management Studio 菜单进入 2 选择服务器和身份验证方式 3 点击连接进入数据库 二 新建数据库 1 数据库的概念
  • 6370小时时,在公司稳定兼职(4000/月)(2016年5月2日 PS:实际上并不是稳定兼职,没项目了就没钱了。)

    周六时 兼职的公司要去了我的工行卡号 以后每月打4000到我的卡里 我需要调整规划了 2016年5月2日 PS 实际上并不是稳定兼职 没项目了就没钱了
  • Linux C文件IO操作

    文件IO 在Linux中万物都为文件 普通文件 设备 socket 标准输入输出等等 常用接口 Method Parameters Descriptions Return H open char name int flags mode 打开
  • python学习3.1

    一 if 语句的使用 if 后的语句是否执行 也跟缩进有关 1 if else eg 输入 bands oasis the beatles eagles the who the kinks for band in bands if band
  • Alist搭建

    Alist简介 一个支持多种存储的文件列表程序 AList设计易于安装 可以在所有平台上使用 支持多个存储提供商 包括本地存储 阿里云盘 OneDrive Google Drive 等 且易于拓展 支持所有 WebDAV 存储 支持视频 音
  • Python tkinter如何把窗口在屏幕中央居中

    Python tkinter如何把窗口在屏幕中央居中 coding utf 8 import tkinter as tk 创建 Tkinter 窗口 root tk Tk 设置窗口大小 root geometry 400x300 获取屏幕宽
  • 企业微信消息多久可以撤回?企业微信怎么查看撤回的消息?

    大家都知道 个人微信是可以撤回两分钟以内的消息 超过两分钟就无法撤回了 那企业微信可以撤回发送了多久的消息呢 撤回的消息还能够查看吗 跟着企业微信服务商艾客scrm小编 一起来看看吧 其实 我们使用任何一个聊天工具聊天的过程中 撤回消息在所
  • Unity URP渲染管线与内置渲染管线的性能差别

    首先 我们来了解一下Unity的内置渲染管线 内置渲染管线是Unity较早版本中使用的默认渲染管线 它使用的是传统的图形渲染技术 内置渲染管线提供了一系列的渲染功能 如阴影 反射 抗锯齿等 但是 由于其较为庞大且复杂的设计 它的性能相对较低
  • qt动态显示当前时间如何实现

    Qt qt动态显示当前时间如何实现 vestinfo 1 票 182 include mainwindow h include ui mainwindow h include
  • Java面向对象编程

    第一章 类与对象 面向对象简介 面向过程指的是面对于一个问题的解决方案 更多情况下不会做出重用的设计 面向对象主要设计形式为模块化设计 可以进行重用配置 更多情p况下考虑的是标准 然后根据标准进行拼装 面向对象有三个主要特性 封装性 内部的
  • 【目标检测】Mask RCNN的训练数据集是什么?(含labelimg和labelme的讲解)

    文章目录 一 训练数据集 二 标注工具介绍 2 1 labelimg介绍 2 2 labelme介绍 2 3 两者的对比 三 制作数据案例 在看完何凯明大神的Mask RCNN的时候 突然想到了一个问题 那就是Mask RCNN的训练数据集
  • JAVA-使用Thumbnails压缩图片

    使用Thumbnails压缩图片
  • 休息是不可能休息的

    654 最大二叉树 分析 相比较遍历顺序构建二叉树 这个相对简单 思路 每次找到数组最大值 然后分割数组 class Solution public TreeNode judge vector
  • VersionCode和VersionName的区别

    最近在研究Android4 1的新功能 增量升级 判断客户端apk的版本号和服务器端的版本号在清单文件中VersionCode和VersionName的区别 记录一下 方便自己或者用到的朋友查看 先上结论 Google为APK定义了两个关于
  • 视频场景切换检测(镜头边界检测、镜头分割)

    个人简介 深度学习图像领域工作者 总结链接 链接中主要是个人工作的总结 每个链接都是一些常用demo 代码直接复制运行即可 包括 1 工作中常用深度学习脚本 2 torch numpy等常用函数详解 3 opencv 图片 视频等操作 4
  • 深入探索C++类的const成员函数

    深入探索C 类的const成员函数 const 成员变量的用法和普通 const 变量的用法相似 只需要在声明时加上 const 关键字 初始化 const 成员变量只有一种方法 就是通过构造函数的初始化列表 const 成员函数可以使用类