C++基础(三)

news2024/9/22 7:32:59

1.再探构造函数

之前的构造函数,初始化成员变量主要使用函数体内赋值,构造函数初始化还有一种方式,就是初始化列表,初始化列表的使用方式是以一个冒号开始,接着是一个以逗号分隔开的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式

	Date(int year, int month, int day)
	
		:_year(year)
		, _month(month)
		, _day(day)
	{}

每个成员变量在初始化列表只出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方

引用成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否者编译报错

//text.cpp
#include<iostream>
using namespace std;

class Date
{
public:
	Date(int& xx, int year, int month, int day)

		:_year(year)
		, _month(month)
		, _day(day)
//引用类型,静态变量初始化,没给默认构造,系统虽然自动生成,还是会走初始化列表
		 ,_n (1)
		,_ref(xx)

	{}
	
private:
	
	//声明
	int _year;
	int _month;
	int _day;
	const int _n;
	int& _ref;
};


int main()
{
	int xx = 5;
	//对象定义
	Date d1(xx, 2024,7, 15);
	
	return 0;
}
  • C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的
//text.cpp
#include<iostream>
using namespace std;

class Time
{
public:
	Time(int hour)
		:_hour(hour)
	{
		//cout << "Time()" << endl;
	}

private:
	int _hour;
};

class Date
{
public:
	Date(int& xx, int year, int month, int day)

		:_year(year)
		, _month(month)
	
	{}	

void	Print()
	{
	cout << _year <<" " << _month <<" " << _day << endl;
	}
private:

	//声明 ,缺省值->初始化列表用的
	int _year=1;
	int _month=1;
	int _day=1;
Time  _t= 1;
};


int main()
{
	//对象定义
	Date d1(xx, 2024,7, 15);
	d1.Print();
	return 0;
}

 初始化列表有的用初始化列表给的值,没有则走默认构造的缺省值。初始列表没给_day赋值,但是声明时赋了缺省值,所以对象声明时即便给了_day=15,但是初始化列表并没有对_day赋值 所以_day初始化为了1

尽管使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表就会使用这个缺省值,如果你没有给缺省值,对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译报错

总结:

每个成员都要走初始化列表

  1. 在初始化列表的成员
  2. 没有在初始化列表的成员

         a.声明的地方有缺省值

         b 没有缺省值

               x :内置类型,不确定,看编译器,大概率是随机值

               y:自定义类型,调用默认构造函数,没有默认构造就报错

      3.引用const 没有默认构造自定义 ,必须在初始化列表完成初始化

初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的先后顺序无关,建议顺序和初始化保持一致

//text.cpp
#include<iostream>
using namespace std;

class A
{
public:
	A(int a)
		:_a1(a)
		,_a2(_a1)
	{}
	void Print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a1=2;
	int _a2=2;
};




int main()
{
	A aa(1);
	aa.Print();
	return 0;
}

 _a2先声明,但是用_a1初始化_a2显然不合理,C++中给变量开内存的顺序跟变量声明一致,所以这里_a2给的是随机值,_a1是1

 2.static

静态成员函数可以为所有成员所共享,不属于莫格具体的对象,不存在对象中,存放在静态区

//text.cpp
#include<iostream>
using namespace std;

class A
{
public:
	A(int a)	
	{}
	~A()
	{}
private:
//类内声明
static	int _a;
	
};

int main()
{
	//计算A的大小
	cout << sizeof(A) << endl;
	return 0;
}

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

//类外初始化
int A::_a = 1;
  • 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针
  • 静态成员函数中可以访问其他的静态成员,但不能访问非静态的,因为没有this指针
  • 非静态的成员函数,可以访问任意的静态成员变量和静态成员函数
class A
{

	static int Getint()
	{
		//不能访问非静态的成员变量,编译器报错,因为静态成员函数没有this指针
		a++;
	}
private:
	int a;
static	int _a;
	
};
  • 突破类域就可以访问静态成员,可以通过类名::静态成员或者 对象.静态成员来访问静态成员变量和静态成员函数
  • 静态成员也是类的成员,受public,protected,private访问限定符的限制
  • 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是给构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表

3.友元

class A

{    //前置声明,否者A的友元函数声明编译器不认识B
	class B;
	//友元函数声明
	friend void func(const A&aa,const B&bb);
	//友元类声明
	friend class B;
private:
	int a;
static	int _a;
	
};
class B
{
};
  • 友元提供一种突破访问限定符封装的方式,友元分为友元函数和友元类,在函数声明或者类声明的前面加friend,并把友元声明放到一个类的里面
  • 外部友元函数可访问类的私有和保护成员,友元函数仅仅是一种声明,他不是类的成员函数
  • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元类的成员函数都可以是另一个类的友元函数,都可以访问另一个类的私有和保护成员
  • 友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元
  • 友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是B的友元
  • 为了提供便利,但是友元会增加耦合度,破坏了封装,所以友元不适合多用

4.内部类

//text.cpp
#include<iostream>
using namespace std;

class A
{public:
	class B {//B默认是A的友元,B可以睡衣访问A
	public:
		void foo(const A& a)
		{
			cout << _k << endl;//ok
			cout << a._h << endl;//ok
		}
	private:
		int _b = 1;
	};
 
private:
	int _h=1;
static	int _k;
	
};


int main()
{
	cout << sizeof(A) << endl;

	return 0;
}

  •  如果一个类定义在另一个类的内部,这个内部类就叫做内部类,内部内是一个独立的类,跟定义在全局相比,他只是受外部类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类

  • 内部类默认是外部类的友元,可以随意访问
  • 内部类本质也是一种封装,当A类跟B类关系紧密,A类实现出来主要就是给B类使用的,那么就可以考虑把A类设计成B类的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地方都用不了

5.匿名对象

//有名对象

A aa1;
A  aaa(1);
//可以这样定义类
A a11();
//不能这样定义,会产生歧义,编译器不知道这是函数声明还是定义类

//匿名对象
A();
A(1);

用类型(实参)定义出来的对象叫匿名对象,相比之前的定义的类型对象名(实参)定义出来的叫友名对象

匿名对象声明周期只在当前一行,一般临时定义一个对象当前用一下即可,就可以定义匿名对象

//text.cpp
#include<iostream>
using namespace std;

class A
{public:
	
	A(int a=0)
	{
	}
	~A()
	{}
	string Print()
	{
		return "2024-7-15";
}
	
};


int main()
{//定义在使用
	A a;
	cout << a.Print() << endl;
	//直接匿名使用
	cout << A().Print() << endl;

	return 0;
}

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

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

相关文章

系统架构师考点--软件工程(上)

大家好。今天我来总结一下软件工程的相关考点。这部分是考试的重点。在上午场客观题、下午场案例题以及下午场论文都有可能考到&#xff0c;在上午场客观题中大约占12-15分左右。 一、软件工程概述 软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析过…

3d导入模型后墙体变成黑色?---模大狮模型网

在展览3D模型设计领域&#xff0c;技术和设计的融合通常是创意和实现之间的桥梁。然而&#xff0c;有时设计师们会遇到一些技术上的挑战&#xff0c;如导入3D模型后&#xff0c;墙体却突然变成了黑色。这种问题不仅影响了设计的视觉效果&#xff0c;也反映了技术应用中的一些复…

数据结构(4.4)——求next数组

next数组的作用:当模式串的第j个字符失配时&#xff0c;从模式串的第next[j]的继续往后匹配 求模式串的next数组(手算) next[1] 任何模式串都一样&#xff0c;第一个字符不匹配时&#xff0c;只能匹配下一个子串&#xff0c;因此&#xff0c;往后&#xff0c;next[1]都无脑写…

数据库学习作业

使用mysgldump命令备份数据库中的所有表 备份booksDB数据库中的books表 使用mysgldump备份booksDB和test数据库(test数据库自行准备) 使用mysq1命令还原第二题导出的book表 进入数据库使用source命令还原第二题导出的book表 创库&#xff0c;建表 建表的结果 插入数据 使用mysg…

医院同步时钟,构建医院零误差时间环境

在医院这个分秒必争、责任重大的场所&#xff0c;时间的准确性和一致性至关重要。医院同步时钟的应用&#xff0c;为构建医院零误差时间环境提供了坚实的保障。 一、医院同步时钟应用原因 首先&#xff0c;医疗工作的精确性和协同性依赖于统一且准确的时间。从手术的安排到药物…

MySQL篇:事务

1.四大特性 首先&#xff0c;事务的四大特性&#xff1a;ACID&#xff08;原子性&#xff0c;一致性&#xff0c;隔离性&#xff0c;持久性&#xff09; 在InnoDB引擎中&#xff0c;是怎么来保证这四个特性的呢&#xff1f; 持久性是通过 redo log &#xff08;重做日志&…

解析CQRS架构模式

在日常开发过程中&#xff0c;关于如何正确划分操作的边界和职责一直是我们需要考虑的一个核心问题。针对这个问题&#xff0c;业界也诞生了一些新的设计思想和开发模式&#xff0c;其中最具代表性的就是今天要介绍的CQRS。 CQRS的全称是Command Query Responsibility Segregat…

图——图的遍历(DFS与BFS)

前面的文章中我们学习了图的基本概念和存储结构&#xff0c;大家可以通过下面的链接学习&#xff1a; 图的定义和基本术语 图的类型定义和存储结构 这篇文章就来学习一下图的重要章节——图的遍历。 目录 一&#xff0c;图的遍历定义&#xff1a; 二&#xff0c;深度优先…

【java计算机毕设】网上购书管理系统MySQL servlet JSP项目设计源代码 期末寒暑假作业 小组作业

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】网上购书管理系统MySQL servlet JSP项目设计源代码 期末寒暑假作业 小组作业 2项目介绍 系统功能&#xff1a; servlet网上购书管理系统包括管理员、用户两种角色。 管理员功能包括订单管理&#xff08;已…

前端Vue组件化实践:自定义加载组件的探索与应用

在前端开发领域&#xff0c;随着业务逻辑复杂度的提升和系统规模的不断扩大&#xff0c;传统的开发方式逐渐暴露出效率低下、维护困难等问题。为了解决这些挑战&#xff0c;组件化开发作为一种高效、灵活的开发模式&#xff0c;受到了越来越多开发者的青睐。本文将结合实践&…

MySQL下载安装使用教程图文教程(超详细)

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这一章节我们使…

Windows安装和使用Doccano标注工具

简介 开源链接&#xff1a;GitHub - doccano/doccano: Open source annotation tool for machine learning practitioners. Open source annotation tool for machine learning practitioners. Doccano是一款开源的文本标注工具&#xff0c;由人工智能公司Hironsan开发并在G…

uni app 本地打包apk 教程

前言: 各位同学大家好,最近帮别人打包了一个 uni 的项目编译成apk 所以觉得必要分享下。 上效果图 原始工程 这种uni 原始的工程我们直接 这样我们就可以运行到我们的模拟器或者真机上面去 手动打包 开发环境 Android Studio 下载地址:An

1讲8小时!张宇新36讲怎么学效果最大化?

别怕&#xff01;解决以下问题&#xff0c;就能让学习效果最大化。 1. 理解有难度。 如果你习惯传统教学模式&#xff0c;例如武忠祥老师的强化课&#xff0c;可能会觉得张宇36讲信息量太大&#xff0c;难以在短时间内消化和理解。 这是因为&#xff0c;考研数学教学的一端&a…

一个审计人为什么要辞职去日本做码农??

今天翻阅报道的时候&#xff0c;看到一篇记者采访记录&#xff1a; 文章的题目是&#xff1a;“审计人辞职去日本做码农的心路历程”。由于标题吸引住了我&#xff0c;我就点进去了看看。 被采访的对象&#xff1a;她在国内审计行业工作两年多后&#xff0c;自学编程&#xf…

Cesium--获取当前相机中心与地面的射线焦点

本文记录获取当前相机中心与地面的射线焦点的方法&#xff0c;可用于视角缩放过程中&#xff0c;控制视角自动平滑切换到二维等场景&#xff1a; 方法一定是视角中心能与地面有交集&#xff0c;如果对着地平线或对着天空肯定是没效果的。直接放代码&#xff1a; //调整相机到正…

计算机志愿攻略,高考生的必读

高考结束 又一年高考结束了 1342万学子们寒窗苦读十二载 迈入考场的那一刻 既紧张又兴奋 即使过去很多年 我仍然能回忆起当年的情景 当高考结束的铃声响起 所有的紧张和压力仿佛瞬间释放 走出来的那一刻 不管结果如何 我们都为自己能够勇敢地走过这段旅程而感到骄傲 …

基于Three.js实现三维空间中的箭头移动动画

继上一篇文章中实现了三维管道的可视化和流动模拟,最近需要基于曲面做三维物体的移动动画效果,特别是箭头等指向性物体的移动,因此就编写了以下方案,主要实现了三维空间内箭头等物体的创建和指向调整及动画效果等,具体如下: 1.基于Thee.js实现箭头等物体创建-THREE.Arrow…

解读网传《深圳IT圈⭕新解读八小时工作制》

网传深圳IT圈的新解读八小时工作制 工作时间安排&#xff1a; 10:00-12:0014:00-18:0019:00-21:00 初看&#xff1a;有惊喜 上午开始时间晚&#xff1a;相对于传统的9点开始&#xff0c;这种安排允许员工有更多的早晨时间&#xff0c;可以用来休息或处理个人事务。下午和晚上分…

S7-200smart与C#通信

https://www.cnblogs.com/heizao/p/15797382.html C#与PLC通信开发之西门子s7-200 smart_c# s7-200smart通讯库-CSDN博客https://blog.csdn.net/weixin_44455060/article/details/109713121 C#上位机读写西门子S7-200SMART PLC变量 教程_哔哩哔哩_bilibilihttps://www.bilibili…