const/static修饰成员函数+初始化列表

news2024/7/6 18:34:26

一、const修饰成员函数

首先,我们知道,所有的成员函数(除static修饰的),编译器都会隐式传递一个this指针。

它的默认类型为 Type* const this,即this指针只能指向最左边的第一个传入的对象。

const修饰成员函数就是将其类型改变成为 const Type* const this,即缩小了权限,在成员函数内部不能修改传入的这个对象。

void Print()
{
    cout << "Print()" << endl;
    cout << "year:" << _year << endl;
    cout << "month:" << _month << endl;
    cout << "day:" << _day << endl << endl;
}
void Print() const
{
    cout << "Print()const" << endl;
    cout << "year:" << _year << endl;
    cout << "month:" << _month << endl;
    cout << "day:" << _day << endl << endl;
}

例如:一个日期类中,有2个Print函数。(由于const修饰了第一个形参this指针,两个函数的参数是不同的,构成函数重载)

Date d1(2022,1,13);
d1.Print();
const Date d2(2022,1,13);
d2.Print();

对于 Date类型的d1,2个Print函数都可以调用。

对于const Date类型的d2,只能调用加了const修饰的Print函数。(权限问题)

 非const对象可以调用两种成员函数,const对象只能调用const修饰的成员函数。

 注意:成员函数直接如果要相互调用,会将this指针依次传递,传递过程中,权限只能平移或者缩小。因此3成立,4不成立。

 总结:const修饰成员函数实际上是缩小了this指针的权限,变为只读。

1、方便了const成员能够调用这个成员函数。 2、成员函数互相嵌套时,要注意权限问题。

3、对于那些不修改对象成员变量的函数最好加上const修饰。同时,其它参数,可以利用const+引用提高效率和传参范围(能否传入const修饰的对象)

二、初始化列表

对于构造函数(包括拷贝构造),可以利用函数体内赋值和初始化列表对其进行初始化。

注:这里由于函数体内可以多次赋值,实际上并不是严格的初始化。

 以上3种情况必须使用初始化列表进行初始化。

对于引用成员变量:由于引用的特点,只能作为一个对象的别名,因此必须在定义时就初始化,而不能采取先定义,后赋值的办法。

对于const成员变量:必须在定义时就赋一个初始值,因为后续它不能被赋值改变。

对于没有默认构造函数的自定义类型成员

默认构造函数可以认为是可以不用传入参数的 

 

对于Myqueue这个类中的两个Stack类型的对象。

不使用初始化列表,只能让编译器调用它们的默认构造函数,得到两个popst和pushst初始值完全相同,都为Stack的构造函数中的默认值。

使用初始化列表,可以对Myqueue的对象q2传入参数,然后可以利用初始化列表对两个popst和pushst分别进行初始化,使得自定义类型初始化内容不同。

注:

3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。


 三、static成员函数+变量

1、static成员函数

static修饰的成员函数,称之为静态成员函数。

静态成员函数不用传递this指针,即可以不依靠实例化的对象来调用

 

当静态成员函数是public时,可以在外部直接使用类名调用,不需要先实例化一个对象。

 1、非静态成员变量是用this找到的,因此找不到具体是哪个对象的成员变量。

 2、普通成员函数第一个参数需要传递this指针,静态成员函数没有,所以内部不能调用。

3、const是用来修饰this指针的,没有this指针,自然不能加const。

2、static成员变量

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量。
静态成员变量一定要在类外进行初始化(规定)。

面试题:实现一个类,计算程序中创建出了多少个类对象

class A
{
public:
    A() { ++_scount; }
    A(const A& t) { ++_scount; }
    ~A() { --_scount; }
    static int GetACount() { return _scount; }
private:
    static int _scount;
};
int A::_scount = 0;

在private内定义一个静态的成员变量_scount(类内声明,类外定义并初始化为0)

这样既可以保证封装性,又可以完成其作为静态变量,不会随意销毁,用来统计对象个数的工作。

特性:

1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

_scount可以不用对象直接访问,但是由于其被private修饰,只能在类内使用。可以使用一个static修饰的静态成员函数,用来返回_scount的值,在外部只需要调用GetAcount函数即可。

这里我们可以看出,静态成员函数和变量可以搭配使用,或者说:静态成员函数可以搭配private修饰的静态成员变量使用。

四、友元函数/类

1、友元函数

class Date
{
    friend ostream& operator<<(ostream& _cout, const Date& d);
    friend istream& operator>>(istream& _cin, Date& d);
public:
    Date(int year = 1900, int month = 1, int day = 1)
        : _year(year)
        , _month(month)
        , _day(day)
        {}
private:
    int _year;
    int _month;
    int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
    _cout << d._year << "-" << d._month << "-" << d._day;
    return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
    _cin >> d._year;
    _cin >> d._month;
    _cin >> d._day;
    return _cin;
}

对于<<流插入和>>流提取操作符,在类内部成员函数使用时,由于this指针是默认的第一个参数,为对象的地址,不符合我们的习惯cout<<xxx,和xxx>>cin,就需要将<<和>>在类的外部进行重载

但是在外部就不能访问private私有变量了。

此时可以在类的内部任意位置,在该函数的前面加上friend使其变为这个类的朋友,然后就可以在类的外部访问私有变量了。

注意:

友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同

2、友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
且A是B的友元类,A可以访问B中非公有成员,B不可以访问A的。

 五、内部类

特性:
1. 内部类可以定义在外部类的public、protected、private都是可以的。
2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
3. sizeof(外部类)=外部类,和内部类没有任何关系

 当然,如果定义在private内,就不能直接在外部通过A::B bb1来创建对象了。

六、匿名对象

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution {
public:
	Solution(int x,int y)
	{}
	int Sum_Solution(int n) {
		//...
		cout << "Sum_Solution(int n)" << endl;
		return n;
	}
};

 七、连续多次构造编译器的优化

这里的构造包括构造函数和拷贝构造。在一个表达式中,如果多次出现构造,编译器会进行优化,减少实际拷贝的次数,从而提高效率。

A func5()
{
	A aa;
	return aa;
}

对于func5这个函数,创建对象aa,调用一次构造函数,然后返回值为A,需要额外进行一次拷贝构造。

 返回的这个临时对象具有常属性,必须用const引用来接收。

 连续的拷贝构造---->优化为直接构造。

ra1:2个拷贝构造优化为1个拷贝构造

ra2:拷贝构造+赋值构造,编译器不优化。

目录

一、const修饰成员函数

二、初始化列表

​编辑 三、static成员函数+变量

1、static成员函数

2、static成员变量

特性:

四、友元函数/类

1、友元函数

2、友元类

 五、内部类

六、匿名对象

 七、连续多次构造编译器的优化


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker容器体系结构及特点

Docker容器体系结构及特点 Docker是一个应用容器引擎&#xff0c;通过Docker&#xff0c;管理员可以非常方便地对容器进行管理。Docker基于Go语言开发&#xff0c;并且遵从Apache 2.0开源协议。 Docker提供了对容器镜像的打包封装功能。利用Docker&#xff0c;开发者可以将他…

2023 最新版IntelliJ IDEA 2023.1创建Java Web 项目详细步骤(图文详解)

文章目录 &#x1f9ed; 版本情况JavaIDEATomcatmaven &#x1f30f; 创建步骤&#x1f697; 1、依次点击File >> New >> Project&#x1f693; 2、选择New Project 输入自己的项目名&#xff0c;选择JDK版本&#xff0c;而后点击create进行创建&#x1f695; 3、鼠…

开新能源汽车有充电焦虑吗?2022年国内充电桩数量已达521万台

哈喽大家好&#xff0c;新能源汽车的不断普及使充电桩市场快速发展起来&#xff0c;同时充电桩的技术正在不断改进&#xff0c;包括充电速度、安全性、互联网功能等多个方面。相比与日渐壮大的新能源汽车用户规模&#xff0c;充电桩的建设相对发展速度较慢&#xff0c;近几年来…

网络编程代码实例:守护进程版

文章目录 前言代码仓库内容目录结构代码结果总结参考资料作者的话 前言 网络编程代码实例&#xff1a;守护进程版。 代码仓库 yezhening/Environment-and-network-programming-examples: 环境和网络编程实例 (github.com)Environment-and-network-programming-examples: 环境…

XShell配置以及使用教程

目录 1、XShell介绍 2、安装XShell 1. 双击运行XShell安装文件&#xff0c;并点击“下一步” 2. 点击“我接受许可证协议中的条款”&#xff0c;点击“下一步” 3. 点击“浏览”更改默认安装路径&#xff0c;点击“下一步” 4. 直接点击“安装” 5. 安装完成&#xff0…

C语言小游戏的实现——三子棋

前言 Hello&#xff01;友友们&#xff0c;前边我们已经学习了C语言的基础知识&#xff0c;但单纯的理论和简单的代码演示是无法真正做到巩固所学的知识的&#xff0c;那么今天我将会带领大家&#xff0c;根据之前所学的知识&#xff0c;来写一个三子棋小游戏。 目录 前言 总…

从C出发 31 --- 指针专题经典问题剖析

int a 0; int* p &a; //p作为指针指向了a, p 保存的是a 变量的内存地址&#xff0c;// p 这个指针本质是变量&#xff0c;这个变量有没有内存地址&#xff1f;// 有内存地址&#xff0c;为什么&#xff1f;// 因为它作为变量&#xff0c;肯定要占用内存空间的// p 这个变…

第十一章 使用Bind提供域名解析服务

文章目录 第十一章 使用Bind提供域名解析服务一、DNS域名解析服务1、DNS简介2、服务器类型3、13台根DNS服务器的具体信息 二、安装Bind服务程序1、Bind简介2、Bind安装3、关键配置文件4、修改主配置文件5、正向解析实验&#xff08;1&#xff09;、编辑区域配置文件&#xff08…

processing官方教程笔记(附加官网链接)更新中~

官方参考文档&#xff1a;https://processing.org/reference 官网视频&#xff1a;https://www.youtube.com/user/shiffman/playlists?view50&sortdd&shelf_id2 b站up主转载官方视频&#xff1a;https://www.bilibili.com/video/BV147411d7kY?p1&vd_source07ce5c…

【计算机三级网络技术】 第六篇 真题练习

文章目录 IPS&#xff08;入侵防护系统&#xff09;相关知识点蓝牙服务器技术DNS 服务器WWW 服务器FTP 服务器邮件&#xff08;Winmail 邮件服务器&#xff09;生成树协议IEEEVLAN 标识的描述DHCP 服务器 IPS&#xff08;入侵防护系统&#xff09;相关知识点 1、入侵防护系统&…

迪赛智慧数——柱状图(象形标识图):在选择另一半时,你更看重的是?

效果图 好看只排第六&#xff0c;第一确实众望所归&#xff01;当代男女择偶标准出炉&#xff0c;一张图带你看清。 女性挑选另一半时&#xff0c;她们更看重伴侣收入高、职业体面、工作能力强、受教育程度高&#xff0c;还得和自己有共同话题。 男性择偶观和女性恰恰相反&am…

第二届网刃部分WP

第二届网刃部分WP 玩坏的winxp 用VM打开附件时候打不开&#xff0c;后来用DiskGenius软件打开&#xff0c;发现桌面中存在有五张图片 在图片meiren.png中发现有隐藏压缩包 foremost分离文件&#xff0c;发现图片 010查看发现还有一层压缩包&#xff0c;再次分离发现压缩包…

自动售货机程序找零博图程序实现

1、操作界面 2、程序实现 REGION 找零确认 IF #找零确认 THEN //复位 #"50元张数" : 0.0; #"20元张数" : 0.0; #"10元张数" : 0.0; #"5元张数" : 0.0; #"1元张数…

Mysten Labs宣布推出积极贡献者和早期支持者ACES计划

Mysten Labs宣布推出积极贡献者和早期支持者&#xff08;ACES&#xff0c;Active Contributors & Early Supporters&#xff09;计划。这是对进入Sui主网的社区成员所做努力的巨大认可。 如果您在5月3日Sui主网启动之前就加入Sui Discord&#xff0c;请于5月18日凌晨2点&a…

JUC并发编程16 | CAS自旋锁

CAS自旋锁 是什么&#xff0c;干什么&#xff0c;解决了什么痛点&#xff1f;如何解决&#xff0c;如何使用。 原子类&#xff1a;java.util.concurrent.atomic 在没有CAS之前&#xff0c;多线程环境不使用原子类保证线程安全i等操作&#xff0c;会出现数据问题&#xff0c;…

LeetCode特训 -- Week3 (字符串)

目录 字符串基础 字符串基本操作 字符串匹配算法 字符串异位词问题 分组分类问题和快速查找数据结构之间存在一定的关系。 字符串回文串问题 留下悬念&#xff1a;高级字符串算法题目(字符串 dp) 字符串基础 字符串定义&#xff1a;n个字符顺次排列而成的序列. 子串&…

MySQL好玩新特性:离线模式

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;Yejinrong/叶金荣文章来源&#xff1a;GreatSQL社区原创 继续吹MySQL 8.0~ 在以前&#xff0c;当需要对MySQL数…

CVPR 2023 | VoxelNeXt实现全稀疏3D检测跟踪,还能结合Seg Anything

在本文中&#xff0c;研究者提出了一个完全稀疏且以体素为基础的3D物体检测和跟踪框架VoxelNeXt。它采用简单的技术&#xff0c;运行快速&#xff0c;没有太多额外的成本&#xff0c;并且可以在没有NMS后处理的情况下以优雅的方式工作。VoxelNeXt在大规模数据集nuScenes、Waymo…

《编程思维与实践》1064.A-B(Big Integer)

《编程思维与实践》1064.A-B(Big Integer) 题目 思路 两个大整数做减法有可能出现结果为负的情况,因此结构体BIGINT需要补充符号位sign, 因为减法是个位对齐进行操作,为了方便起见,本题还是采用逆序(个位开始)存储. 注意到本题的两个整数均非负,所以不需要考虑转化为加法的情况…

TOOM舆情监测系统:从原理到应用

舆情监测系统是一种可以帮助企业、政府等机构了解公众对自己的看法和态度&#xff0c;提前发现和预测可能出现的危机或负面舆情&#xff0c;从而进行预警和应对的工具。本文将从原理到应用&#xff0c;通过国内具体案例分析&#xff0c;探讨舆情监测系统的相关知识。 一、舆情…