C++初阶篇----类与对象下卷

news2024/11/23 13:19:22

目录

  • 1.再谈析构函数
    • 1.1构造函数体赋值
    • 1.2 初始化列表
    • 1.3 explicit关键字
  • 2.Static成员
    • 2.1概念
    • 2.2 特性
  • 3.友元
    • 3.1 概念
    • 3.2友元函数
    • 3.3 友元类
  • 4.内部类
    • 4.1 概念
  • 5.匿名对象
    • 5.1 概念
  • 6.拷贝对象时的一些编译器优化
  • 7.再次理解封装

1.再谈析构函数

1.1构造函数体赋值

在对类的实例化后,也就是创建对象,都会自动调用构造函数
当对象中某一个成员已经有了初始值,但其他成员变量仍需要初始化的时候,构造函数体中的语句只能将其称为赋初值,初始化只能初始化一次,而构造函数体内可以多此赋值

1.2 初始化列表

初始化列表的概念:是一种用于在对象创建时初始化成员变量的语法。
初始化列表的组成:
以一个冒号(:)开始,接着是一个以逗号(,)分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值表达式。这些初始值将按照它们在初始化列表中的顺序来初始化对象的成员变量。

class M
{
public:
	M(char name, int age, char sex):_name(name),_age(age),_sex(sex)
	{
		if (_age < 0)
			cout << "输入错误" << endl;
		else
		{
			printf("%c", "%c", _name, _sex);
		}
	}
private:
	char _name;
	int _age;
	char _sex;
};

注意:

  1. 每个成员变量在初始化列表中只能出现一次
  2. 引用成员,const变量,自定义类型成员(无默认构造函数) ,必须放在初始化列表位置初始化
class A
{
public:
	A(int num) :_num(num)
	{	
	}
private:
	int _num;
};

class M
{
public:
	M(int x,char name, char sex):_aa(x),_name(name),_sex(sex)
	{
		//if (_age < 0)
			//cout << "输入错误" << endl;
	}
private:
	char& _name;//引用
	const char _sex;//常变量
	A _aa;//自定义
};

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

class N
{
public:
	N(int a=2) : _b(a),_a(_b)  //在这的顺序是先赋值给_b,再赋值给_a
	{
		cout << _a << endl << _b << endl;
	}
private:
	int _a;
	int _b;
};

int main()
{
	N n;
	return 0;
}

在这里插入图片描述

1.3 explicit关键字

explicit 关键字用于修饰单参数构造函数,它表明该构造函数是显式的,即不会隐式地被用于隐式类型转换。

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。

不加explicit:

class N
{
public:
	//这里不加explicit
	//explicit N*(int a =2)
	N(int a=2) 
	: _a(a)  
	{
		cout << _a << endl;
	}
private:
	int _a;
};
void fun(N n)
{

}

int main()
{
	fun(1);//本应该传自定义类型N,但是编译器做了隐式转换,直接转换成 n(1)
	return 0;
}

在这里插入图片描述
加了explicit:
在这里插入图片描述
编译器会直接报错,不能实现隐式转换

2.Static成员

2.1概念

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

静态成员是属于类本身而不是类的实例的成员。静态成员可以被所有该类的实例共享,并且可以通过类名访问,而不需要创建类的实例。这使得静态成员成为存储类数据和提供类范围功能的有用工具。

class A
{
public:
	A() {
		_a++;
	}
	static int num()
	{
		return _a;
	}
private:
	static int _a;
};
int A::_a = 0;
int main()
{
	A a1, a2;
	cout << A::num() << endl;
	return 0;
}

2.2 特性

  1. 静态成员为所有类对象所共享,不属于某一个具体的对象,储存在静态区(也就与对象实例化无关)
  2. 静态成员变量必须在类外定义,定义时不添加static关键字
  3. 静态成员函数没有隐藏的**this**指针,不能访问非静态成员
  4. 静态成员受public,private,protected访问限定符得限制

注意:静态成员函数是声明为静态的类函数。它们不操作特定的对象实例,因此不能访问非静态成员变量非静态成员函数。可以通过类名直接调用静态成员函数。

3.友元

3.1 概念

友元(friend)是一种机制,允许一个类或函数访问另一个类的私有成员。通过将一个函数或类声明为另一个类的友元,可以允许该函数或类访问该类的私有成员,即使它们通常不能直接访问这些私有成员。
友元提供的是一种突破封装的方式(类比现实中的"开后门")
友元分为:友元函数友元类

3.2友元函数

class Date
{
public:
	friend void Print(const Date a);
	Date(int year=2024, int month=2, int day=29) :_year(year), _month(month), _day(day){}
	
private:
	int _year;
	int _month;
	int _day;
};

void Print(const Date a)
{
	cout << a._day << endl;
}

关于类的输出输入流(友元应用)

class Date
{
public:
	friend ostream& operator<<(ostream& cout, const Date& a);
	friend istream& operator>>(istream& cin, Date& a);
	//friend void Print(const Date& a);
	Date(int year=2024, int month=2, int day=29) :_year(year), _month(month), _day(day){}
	
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& cout, const Date& a)
{
	cout << a._day << " " << a._month << " " << a._year << endl;
	return cout;
}

istream& operator>>(istream& cin, Date& a)
{
	cin >> a._year >> a._month >> a._day;
	return cin;
}

int main()
{
	Date a;
	cin >> a;
	cout << a;

	return 0;
}

在这里插入图片描述

友元函数不是类的成员函数
友元函数不能用const修饰

3.3 友元类

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

  • 友元关系单向,不具有交换性(你是我朋友,不代表我是你朋友)
  • 友元关系不能传递
  • 不能继承
class Date
{
public:
	friend class A;
	friend ostream& operator<<(ostream& cout, const Date& a);
	friend istream& operator>>(istream& cin, Date& a);
	//friend void Print(const Date& a);
	Date(int year=2024, int month=2, int day=29) :_year(year), _month(month), _day(day){}
	
private:
	int _year;
	int _month;
	int _day;
};

class A
{
public:
	void Print()
	{
		//访问Date的私有成员
		cout << _num  << endl;
		cout << t._day << " " << t._month << " " << t._year << endl;
		cout << t;
	}
private:
	int _num = 10;
	Date t;
};

int main()
{
	A a;
	a.Print();

	return 0;
}

在这里插入图片描述

4.内部类

4.1 概念

如果一个类定义在另一个类的内部,这个内部类就叫做内部类
它不属于外部,不能通过外部的类的对象去访问内部类的成员

内部类是外部类的友元类,内部类可以访问外部类的对象参数,但是外部类不是内部类的友元

class A
{
private:
	int _x = 10;
	static int a;
public:
	class B
	{
	private:
		int _y = 5;
	public:
		void Print(const A& _A)
		{
			cout << a << endl;
			cout << _A._x << endl;
		}
	};
};
int A::a = 0;
int main()
{
	A::B b;
	b.Print(A());
	return 0;
}

在这里插入图片描述

5.匿名对象

5.1 概念

匿名对象是指在不给对象命名的情况下创建的临时对象。这些对象通常用于某些特定的场景,而不需要通过变量名来引用它们。

class A
{
private:
	int _x ;
public:
	A(int x=10) :_x(x)
	{
		cout << "A()" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
	void Print()
	{
		cout << _x;
	}
};

int main()
{
	A();//生命周期只有这一行
	A().Print();//只调用函数,那么匿名对象非常快捷
	return 0;
}

在这里插入图片描述

6.拷贝对象时的一些编译器优化

在传参嗯哼传返回值的过程中,一般编译器会做一些优化来提高效率(减少不必要的对象的拷贝)

class A
{
private:
	int _x;
public:
	A(int x = 10) :
		_x(x)
	{
		cout << "A(x)" << endl;
	}
	A(const A& a)
	{
		_x = a._x;
		cout << "A(const A& a)" << endl;
	}
	A& operator=(const A& a)
	{
		if(this!=&a)
		{
			_x = a._x;
			cout << "operator=" << endl;
		}
		return *this;
	}
	~A()
	{
		cout << "~A" << endl;
	}
};

void fun(A a)
{}

A fun2()
{
	A a;
	return a;
}

传值传参

int main()
{
	A a(2);
	fun(a);

	return 0;
}

在这里插入图片描述

int main()
{
	fun(A(1));//连续构造+拷贝-》优化为一个构造

	return 0;
}

在这里插入图片描述

int main()
{
	//	fun(A(1));//连续构造+拷贝-》优化为一个构造
	A a = fun2();//  原:函数体一个构造,返回值一个构造,拷贝一个构造-》优化为一个构造
	return 0;
}

在这里插入图片描述

7.再次理解封装

现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。

类是对某一类实体(对象)的来进行描述的,描述该对象的特征属性
在这里插入图片描述

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

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

相关文章

力扣大厂热门面试算法题 - 动态规划

爬梯子、跳跃游戏、最小路径和、杨辉三角、接雨水。每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.05 可通过leetcode所有测试用例。 目录 70. 爬楼梯 解题思路 完整代码 Python Java 55. 跳跃游戏 解题思路 完整代码 Python 代码…

LeetCode每日一题 二叉树的最大深度(二叉树)

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,nul…

大摩突发:将推出比特币ETF

作者&#xff1a;秦晋 随着比特币ETF愈发火爆&#xff0c;华尔街另一家管理1.3万亿美元资产的大型经纪自营商「摩根士丹利」正在蠢蠢欲动&#xff0c;准备进军比特币ETF。 据彭博社数据显示&#xff0c;目前10只比特币现货ETF在上周三创下单日交易新纪录&#xff0c;成交量超过…

太惊艳了!多微信管理利器,让你事半功倍!

作为现代社交媒体的主要平台之一&#xff0c;微信在商务领域中扮演着重要的角色。为了提高我们的工作效率&#xff0c;微信管理系统应运而生。 这个系统可以同时登录多个微信账号&#xff0c;并进行统一管理。除了便捷的登录管理功能外&#xff0c;微信管理系统还提供了许多实…

优思学院|质量和企业的盈利能力有何关系?

质量和企业的盈利能力有何关系&#xff1f;三十年前&#xff0c;这个问题就已经被提出。当时的学者们研究了高质量产品如何带来更高的盈利。虽然这听起来像是老生常谈&#xff0c;但它的真理至今仍深深影响着我们的商业决策。 为了更直观地理解&#xff0c;一些学者绘制了以下…

Redis 核心面试题归纳

文章目录 RedisAOF 相关1. redis AOF 文件备份时&#xff0c;是使用的 write ahead log 的方式吗2. redis 开启AOF后的写入步骤3. redis AOF文件重写过程4.AOF 持久化策略 RDB 相关1.RDB 写入过程rdb 过程中&#xff0c;复制的页表是什么 Redis 主从同步1.PSYNC 和 SYNC 的区别…

Vue 前端开发 v-for和v-if两个指令不能混合使用

原由&#xff1a; 在进行项目开发的时候因为在一个标签上同时使用了v-for和v-if两个指令导致的报错。 提示错误&#xff1a;The undefined variable inside v-for directive should be replaced with a computed property that returns filtered array instead. You should no…

安装QT时,安装进程(qt.tools.perl)运行期间出现错误

安装QT时&#xff0c;安装进程(qt.tools.perl)运行期间出现错误 解决方法

小智浏览器助手

作为使用者来说&#xff0c;这个浏览器头痛的地方就是不能随意的切换地址&#xff0c;每次都要重新配置ini文件 再重新打开。 于是&#xff0c;我想了个办法&#xff0c;在使用前面加个能切换&#xff0c;维护地址的程序&#xff0c;让它来调用这个浏览器不就实现我的要求了&a…

【CSP考点回顾】前缀和数组

一、一维数组前缀和 前缀和算法是一种用于处理数组的技术&#xff0c;它可以快速计算任何连续子数组的和。适合在多次查询中需要求解多个范围和的情况。使用前缀和算法可以将每次求和的时间复杂度从 O(n) 降低到 O(1)。 前缀和的思想是创建一个新数组 A r r Arr Arr&#xff0…

kamailio转发电话到目的地,目的返回失败时再转给其他IP

按图中这样测试&#xff1a; A---->kamailio------->B B返回480等失败错误码&#xff08;非200 OK&#xff09;&#xff0c;能进入failure_route[TOVOICEMAIL]&#xff0c;但是t_relay_to_udp执行失败。 好吧&#xff0c;说是&#xff1a;在 failure_route 中处理的是…

干货!Python函数定义与调用

1.函数定义 函数主要有两部分组成&#xff1a;声明部分和实现部分 def 是 define的简写&#xff0c;表示定义的意思 函数名类似于变量名&#xff0c;遵守标识符命名规则&#xff0c;尽量做到见名知意 ():里面放的是参数列表&#xff0c;参数列表中的参数可以为空 函数体:表…

Claude3荣登榜首,亚马逊云科技为您提供先行体验!

Claude3荣登榜首&#xff0c;亚马逊云科技为您提供先行体验&#xff01; 个人简介前言抢先体验关于Amazon BedrockAmazon Bedrock 的功能 Claude3体验教程登录Amazon Bedrock试用体验管理权限详细操作步骤1.提交应用场景详细信息2.请求模型的访问权限3.请求成功&#xff0c;开始…

Windows下Golang开发环境的安装

以下是在Windows操作系统下安装Go语言环境&#xff08;Golang&#xff09;的步骤。 请注意&#xff0c;安装步骤可能因Go的版本更新而有所变化&#xff0c;以下教程适用于撰写本文时的最新稳定版。 1、下载Go语言安装包 打开Go语言的官方下载页面&#xff1a;https://golang.go…

MySQL高可用性攻略:快速搭建MySQL主从复制集群 !

MySQL高可用性攻略&#xff1a;快速搭建MySQL主从复制集群 &#xff01; MySQL基础知识&#xff1a;介绍MySQL数据库的基本概念和常用命令&#xff0c;如何创建数据库、表、用户和权限管理等。 MySQL安装教程&#xff1a;Centos7 安装MySQL5.7.29详细安装手册 MySQL数据类型&…

Python 过滤函数filter()详解

一、过滤函数定义 它用于对容器中的元素进行过滤处理。 二、 过滤函数语法 filter(function,iterable) 参数function&#xff1a;提供过滤条件的函数&#xff0c;返回布尔型 参数iterable: 容器类型数据 三、过滤函数的应用场景 1、筛选符合条件的元素 需求&#xff1a;在列表…

VMware安装Ubuntu(保姆级)

VMware安装Ubuntu&#xff08;保姆级&#xff09; 文章目录 VMware安装Ubuntu&#xff08;保姆级&#xff09;一、镜像下载二、开始安装①&#xff1a;创建一个新的虚拟机②&#xff1a;开始安装③&#xff1a;安装 ssh 服务 提示&#xff1a;以下是本篇文章正文内容&#xff0…

第1题:两数之和

题目内容&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。…

“比特币刚破6.9万又套牢”?超31万人爆仓11.5亿美元!后市将如何发展?

时隔846天&#xff08;2021年11月10日&#xff09;之久&#xff0c;比特币终于在昨晚最高触及69080美元&#xff0c;再度创下历史新高&#xff0c;引发社群一片感慨&#xff1a;比特币再不亏欠任何人&#xff01; 怎料&#xff0c;比特币刚站上历史高点就急速下挫&#xff0c;一…

Linux基础——进程控制

1. 进程创建 在这之前我们曾了解过进程创建&#xff08;详见进程初识&#xff08;二&#xff09;&#xff09;&#xff0c;我们在这里对fork函数做一些补充 其实对于父子进程来说&#xff0c;若是有一方试图修改数据时&#xff0c;会向物理内存中申请一份新空间&#xff0c;并…