当前位置: 首页 > news >正文

【C++】类和对象(二)

  耐心、韧性、谅解、宽容、包涵,都是爱的代名词。

前言

  这是我自己学习C++的第三篇博客总结。后期我会继续把C++学习笔记开源至博客上。

  上一期笔记是关于C++的类和对象,没看的同学可以过去看看:

【C++】类和对象(一)-CSDN博客https://blog.csdn.net/hsy1603914691/article/details/143213525

初始化列表

1. 在调用构造函数时,成员变量的初始化通常有两种方式:一种是在构造函数体内进行赋值,另一种是通过初始化列表进行赋值

2. 初始化列表的使用方法如下:以冒号开头,随后是一个由逗号分隔的成员变量列表,每个成员变量后面紧跟一对圆括号,括号中包含该变量的初始值或初始化表达式

3. 引用类型的成员变量const修饰的成员变量自定义类型的成员变量必须放在初始化列表进行初始化,否则会编译报错

4. C++11支持在成员变量声明时给缺省值,这个缺省值主要是给没有显示的在初始化列表初始化的成员使用的。

5. 尽量使用初始化列表,因为那些你不在初始化列表初始化的成员也会走初始化列表

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

#include<iostream>
using namespace std;

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

class Date
{
public:
	Date(const int& x, int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
		, _t(12)
		, _ref(x)
		, _n(1)
	{}
	void Print() const 
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year = 10;//可以在声明时候给缺省值
	int _month = 10;
	int _day = 10;
	Time _t; 
	int& _ref; 
	const int _n; 
};

int main()
{
	int i = 0;
	Date d1(i);
	d1.Print();//1 1 1
	return 0;
}

友元 

1. 友元提供了一种突破封装的方式,友元分为:友元函数友元类

2. 友元声明时,需要在友元函数或者友元类前面加friend,并且把友元声明放到对应的类的里面

3. 友元函数可以访问类的私有和保护成员,但不是这个类的成员函数

4. 友元函数可以在类定义的任何地方声明,不受类访问限定符限制

5. 一个函数可以是多个类的友元函数

6. 友元类中所有的成员函数都是另一个类的友元函数,都可以访问另一个类的私有成员和保护成员

7. 友元关系是单向的不能传递的

//友元函数
#include <iostream>
using namespace std;

class B;//先声明一个B类类型,否则A中声明友元函数时,找不到B的类型。

class A 
{
	friend void func(const A& aa, const B& bb);// 友元声明
private:
	int _a1 = 1;
	int _a2 = 2;
};

class B
{
	friend void func(const A& aa, const B& bb);// 友元声明
private:
	int _b1 = 3;
	int _b2 = 4;
};

void func(const A& aa, const B& bb)
{
	cout << aa._a1 << endl;
	cout << bb._b1 << endl;
}

int main()
{
	A aa;
	B bb;
	func(aa, bb);
	return 0;
}
//1
//3
//友元类
#include<iostream>
using namespace std;
class A
{
	friend class B;	// 友元声明
private:
	int _a1 = 1;
	int _a2 = 2;
}; 

class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
	void func2(const A& aa)
	{
		cout << aa._a2 << endl;
		cout << _b2 << endl;
	}
private:
	int _b1 = 3;
	int _b2 = 4;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	bb.func1(aa);
	return 0;
}
//1
//3
//1
//3

内部类 

1. 如果一个类定义在另一个类的内部,那么前面这个类就叫做内部类

2. 内部类是一个独立的类,只是受外部类的类域限制和访问限定符限制。这意味着内部类虽然位于外部类的命名空间内,但并不依赖于外部类的实例,即外部类定义的对象中不包含内部类

3. 内部类默认是外部类的友元类内部类可以访问外部类的成员

3. 内部类本质也是一种封装,当A类跟B类紧密关联,A类的主要功能是为了服务于B类,那么可以考虑把A类设计为B类的内部类,如果将A类放置在B类的privateprotected位置,那么A类就是B类的专属内部类,其他地方都用不了。

#include<iostream>
using namespace std;

class A
{
private:
	static int _k;
	int _h = 1;
public:
	class B // B默认就是A的友元
	{
	public:
		void foo(const A& a)
		{
			cout << _k << endl; //OK
			cout << a._h << endl; //OK
		}
	};
};
int A::_k = 1;
int main()
{
	cout << sizeof(A) << endl;//4
	A::B b;
	A aa;
	b.foo(aa);//1 1
	return 0;
}

static修饰 

1. 使用static修饰的成员变量,称为静态成员变量,静态成员变量必须要在类外初始化

2. 静态成员变量为类的所有对象所共享,不属于某个具体的对象,存放在静态区

3. 使用static修饰的成员函数,称为静态成员函数,静态成员函数没有this指针

4. 可以在静态成员函数中访问静态成员变量,但是不能访问非静态的成员变量,因为静态成员函数没有this指针

5. 可以在非静态的成员函数中访问任意的静态成员变量静态成员函数

6. 突破类域就可以访问静态成员,可以通过 类名::静态成员 或者 对象.静态成员 的方式来访问静态成员变量和静态成员函数

7. 静态成员也是类的成员,也受访问限定符的限制

8. 静态成员变量不能在声明位置给缺省值初始化,因为静态成员变量不属于某个具体的对象,不走构造函数初始化列表。

#include<iostream>
using namespace std;

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;

int main()
{
	cout << A::GetACount() << endl;
	A a1, a2;
	A a3(a1);
	cout << A::GetACount() << endl;
	cout << a1.GetACount() << endl;
	return 0;
}
//0
//3
//3

致谢

  感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!

http://www.dtcms.com/a/106839.html

相关文章:

  • 第三章 知识图谱赋能 RAG:构建结构化知识引擎
  • CoT-VLA:视觉-语言-动作模型的视觉思维链推理
  • 软件工程面试题(二十三)
  • Web服务器主动推送技术(SSE)
  • MongoDB 复制集实战
  • 笔记:docker安装(ubuntu 20.04)
  • C# 中充血模型和‌贫血模型
  • 从查重报告入手的精准论文降重秘籍
  • 基于 Spring Cloud 与 Spring Boot 的工程项目管理系统源码:重塑工程管理新范式​
  • 文件实时备份软件PanguFlow
  • zabbix监控网站(nginx、redis、mysql)
  • 在openharmony中编译部署早期vi工具(附带vi工具源码)
  • 生产管理系统如何破解汽车零部件行业追溯难痛点
  • (Kotlin) Android使用DialogX实现iOS风格底部弹窗(带Toggle开关)
  • 算法与数据结构面试题
  • 【硬件视界8】电源供应器(PSU):计算机的“心脏“
  • 洛谷题单3-P5720 【深基4.例4】一尺之棰-python-流程图重构
  • Tomcat 部署 Jenkins.war 详细教程(含常见问题解决)
  • 存储型XSS漏洞解析
  • springBoot统一响应类型3.5.2版本
  • 【橘子大模型】关于PromptTemplate
  • 定制化管理系统与通用管理系统,谁更胜一筹?
  • MySQL的进阶语法7(索引-B+Tree 、Hash、聚集索引 、二级索引(回表查询)、索引的使用及设计原则
  • ES6对函数参数的新设计
  • 贪心算法,其优缺点是什么?
  • 第二篇:系统分析师——1-6章
  • 深入解析 Spring Boot 测试核心注解
  • 使用UDP建立连接,会存在什么问题?
  • es使用ik分词器并自定义中文词库实现热更新
  • 软件工程13 条法则