IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++基础-静态成员变量和静态成员函数单例模式this指针,常函数和常对象,友元函数 -> 正文阅读

[C++知识库]C++基础-静态成员变量和静态成员函数单例模式this指针,常函数和常对象,友元函数

01 静态成员变量和静态成员函数

1.静态成员变量,在类内声明,类外进行初始化

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:
	Person()
	{
		//m_Age = 10;
	}

	static int m_Age;//加入static就是 静态成员变量,会共享数据
	//静态成员变量,在类内声明,类外进行初始化
};
int Person::m_Age = 0;//类外初始化实现


void test01()
{
	//1.通过对象访问属性
	Person p1;
	p1.m_Age = 10;

	Person p2;
	p2.m_Age = 20;

	cout << "p1.m_Age:" << p1.m_Age << endl;//20
	cout << "p2.m_Age:" << p2.m_Age << endl;//20
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

2.静态成员变量也是有权限的

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:

	static int m_Age;//加入static就是 静态成员变量,会共享数据
	//静态成员变量,在类内声明,类外进行初始化

	int m_A;
	//静态成员变量也是有权限的
private:
	static int m_other;

};
int Person::m_Age = 0;//类外初始化实现
int Person::m_other = 10;


void test01()
{
	//1.通过对象访问属性
	Person p1;
	p1.m_Age = 10;

	Person p2;
	p2.m_Age = 20;

	cout << "p1.m_Age:" << p1.m_Age << endl;//20
	cout << "p2.m_Age:" << p2.m_Age << endl;//20

	//2.通过类名访问属性
	cout << "通过类名访问m_Age:" << Person::m_Age << endl;
	//cout << "通过类名访问m_other:" << Person::m_other << endl;//私有权限在类外无法访问
}

int main(void)
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

3.静态成员函数不可以访问普通成员变量

因普通成员变量可以别共享,所以静态成员函数不可以访问普通成员变量。
原理如下:
在这里插入图片描述

4.普通成员函数 可以访问普通成员变量,也可以访问静态成员变量

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:

	static int m_Age;//加入static就是 静态成员变量,会共享数据
	//静态成员变量,在类内声明,类外进行初始化

	int m_A;

	//静态成员函数
	//静态成员函数不可以访问 普通成员变量
	//普通成员函数 可以访问普通成员变量,也可以访问静态成员变量
	static void func()
	{
		//m_A = 10;//不可以访问
		m_Age = 10;//可以访问静态成员变量
		cout << "静态成员函数 func() 的调用" << endl;
	}

	//静态成员变量也是有权限的
	//静态成员函数也是有权限的
private:
	static int m_other;

	void func2()
	{

	}
};
int Person::m_Age = 0;//类外初始化实现
int Person::m_other = 10;


void test01()
{
	//1.通过对象访问属性
	Person p1;
	p1.m_Age = 10;

	Person p2;
	p2.m_Age = 20;

	cout << "p1.m_Age:" << p1.m_Age << endl;//20
	cout << "p2.m_Age:" << p2.m_Age << endl;//20

	//2.通过类名访问属性
	cout << "通过类名访问m_Age:" << Person::m_Age << endl;
	//cout << "通过类名访问m_other:" << Person::m_other << endl;//私有权限在类外无法访问

	//静态成员函数的调用
	p1.func();
	p2.func();
	Person::func();

	//静态成员函数也是有权限的
	//Person::func2();
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

02 单例模式案例-主席案例

构造函数优于main函数调用,static在编译阶段就构造好了,main函数是在运行阶段才调用

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//创建主席类
class ChairMan
{
private:
	//构造函数私有化
	ChairMan() {
		cout << "主席构造函数调用" << endl;
	}
public:
	static ChairMan* singleMan;
};

ChairMan* ChairMan::singleMan = new ChairMan;

//需求 单例模式 为了创建类中的对象,并且保证只有一个对象实例
void test01()
{
	/*ChairMan c1;
	ChairMan* c2 = new ChairMan;*/

	ChairMan::singleMan;
}

int main(void)
{
	cout << "main函数调用" << endl;//主席先于main的调用
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//创建主席类
class ChairMan
{
private:
	//构造函数私有化
	ChairMan() {
		cout << "主席构造函数调用" << endl;

	}
	//拷贝构造函数私有化
	ChairMan(const ChairMan& c) {}

public:

	//提供get方法访问主席
	static ChairMan* getInstance()
	{
		return singleMan;
	}

private:
	static ChairMan* singleMan;
};
ChairMan* ChairMan::singleMan = new ChairMan;


//需求 单例模式 为了创建类中的对象,并且保证只有一个对象实例
void test01()
{
	/*ChairMan c1;
	ChairMan* c2 = new ChairMan;*/

	/*ChairMan* cm1 = ChairMan::singleMan;
	ChairMan* cm2 = ChairMan::singleMan;*/

	//ChairMan::singleMan = NULL;

	ChairMan* cm1 = ChairMan::getInstance();
	ChairMan* cm2 = ChairMan::getInstance();

	if (cm1 == cm2)
	{
		cout << "cm1和cm2相同" << endl;
	}
	else
	{
		cout << "cm1和cm2不相同" << endl;
	}

	/*ChairMan* cm3 = new ChairMan(*cm1);//构造函数私有化了,不可调用默认构造函数使用值传递,导致不相同
	if (cm3 == cm2)
	{
		cout << "cm3和cm2相同" << endl;
	}
	else
	{
		cout << "cm3和cm2不相同" << endl;
	}*/
}

int main(void)
{
	//cout << "main函数调用" << endl;//主席先于main的调用
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

03 单例模式案例-打印机案例

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

class Printer
{
private:
	Printer() {//:printCount(0){
		//printCount = 0;
	}
	Printer(const Printer& p) {}

public:
	static Printer* getInstance()
	{
		return singlePrinter;
	}

	void doPrintText(string text)
	{
		cout << text << endl;
		printCount++;
	}
	int getPrintCount()
	{
		return printCount;
	}

private:
	static Printer* singlePrinter;
	static int printCount;

};
Printer* Printer::singlePrinter = new Printer;
int Printer::printCount = 0;

void test01()
{
	Printer* printer = Printer::getInstance();
	printer->doPrintText("入职报告");
	printer->doPrintText("加薪申请");
	printer->doPrintText("升级申请");
	printer->doPrintText("退休申请");
	printer->doPrintText("辞职报告");

	cout << "公司打印机使用次数: " << printer->getPrintCount() << endl;
}

int main(void)
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

04 C++对象模型初探-成员变量和成员属性分开处理

1.成员变量和成员属性分开存储

在这里插入图片描述

2.空类的大小为1,每个实例的对象都有独一无二的地址

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{

};

void test01()
{
	cout << "Person 类的大小: " << sizeof(Person) << endl;
	//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述
非静态成员变量。才属于对象身上

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:
	int m_A;//非静态成员变量,属于对象身上
	void func() {}//非静态成员函数,不属于对象身上
	static int m_B;//静态成员变量,不属于对象身上
	static void func2() {};//静态成员变量,不属于对象身上
};
//结论:非静态成员变量。才属于对象身上
void test01()
{
	cout << "Person 类的大小: " << sizeof(Person) << endl;
	//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述
calss默认对齐,可以用#pragma pack(1)删除

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//#pragma pack(1)

class Person
{
public:
	int m_A;//非静态成员变量,属于对象身上
	void func() {}//非静态成员函数,不属于对象身上
	static int m_B;//静态成员变量,不属于对象身上
	static void func2() {};//静态成员变量,不属于对象身上
	double m_C;//16
};
//结论:非静态成员变量。才属于对象身上
void test01()
{
	cout << "Person 类的大小: " << sizeof(Person) << endl;
	//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

05 this指针基本使用

1.this指针指向被调用的成员函数所属的对象

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//#pragma pack(1)

class Person
{
public:
	int m_A;//非静态成员变量,属于对象身上
	void func() {}//非静态成员函数,不属于对象身上
	static int m_B;//静态成员变量,不属于对象身上
	static void func2() {};//静态成员变量,不属于对象身上
	double m_C;//16
};

void test02()
{
	//this指针指向被调用的成员函数所属的对象

	Person p1;
	p1.func();//编译器会默认加一个隐含指针 this指针 在这是Person* this
	//this指针永远指向当前对象

	Person p2;
	p2.func();
}

2.this可以解决命名冲突问题

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;


class Person
{
public:
	//this可以解决命名冲突问题
	Person(int age)
	{
		this->age = age;
	}

	//对比年龄
	void compareAge(Person& p)
	{
		if (this->age == p.age)
		{
			cout << "年龄相等" << endl;
		}
		else
		{
			cout << "年龄不相等" << endl;
		}
	}

	int age;
};

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p1.compareAge(p2);

	cout << "p1.age = " << p1.age << endl;
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

3.*this 链式编程

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;


class Person
{
public:
	//this可以解决命名冲突问题
	Person(int age)
	{
		this->age = age;
	}

	//对比年龄
	void compareAge(Person& p)
	{
		if (this->age == p.age)
		{
			cout << "年龄相等" << endl;
		}
		else
		{
			cout << "年龄不相等" << endl;
		}
	}

	//年龄相加
	Person& plusAge(Person& p)
	{
		this->age += p.age;
		return *this;//this指向对象本体
	}

	int age;
};

void test01()
{
	Person p1(10);

	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p1.compareAge(p2);

	p1.plusAge(p2).plusAge(p2);//链式编程

	cout << "p1.age = " << p1.age << endl;
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

06 空指针访问成员函数

如果成员函数没有用到this,那么空指针可以直接访问
如果成员函数用到this指针,那么注意,可以加if判断,如果this为NULL就return

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:
	void personShow()
	{
		cout << "Person_show" << endl;
	}

	void showAge()
	{
		if (this == NULL)
		{
			return;
		}
		cout << "personAge:" << personAge << endl;
	}

	int personAge;

};

void test01()
{
	Person* p1 = NULL;
	p1->personShow();
	p1->showAge();
}

int main(void)
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:
	void personShow()
	{
		cout << "Person_show" << endl;
	}

	void showAge()
	{
		if (this == NULL)
		{
			return;
		}
		cout << "personAge:" << personAge << endl;
	}

	int personAge;

};

void test01()
{
	Person* p1 = NULL;
	p1->personShow();
	p1->showAge();
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

07 常函数和常对象

常函数,不允许修改this指针指向的值.
常对象,不允许修改属性.
常对象,不可以调用普通成员函数.
常对象,可以调用常函数.

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Person
{
public:

	Person()
	{
		this->m_A = 0;
		this->m_B = 0;
	}

	void showInfo() const//常函数 不允许修改this指针指向的值
	{
		//this->m_A = 10;
		this->m_B = 10;

		cout << "m_A:" << this->m_A << endl;
		cout << "m_B:" << this->m_B << endl;
	}



	int m_A;
	mutable int m_B;//就算是常函数,这个变量还是有修改的需求
};

void test01()
{
	Person p1;
	p1.showInfo();

	//常对象 不允许修改属性
	const Person p2;
	//p2.m_A = 1000;
	//常对象 不可以调用普通成员函数
	//常对象 可以调用常函数
}

int main(void)
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

08 全局函数做友元函数

全局函数写到类中做声明,并且最前面写关键字friend。
友元函数的目的就是访问类中的私有成员属性。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

class Building
{
	//将全局函数变为 友元函数
	friend void goodGay(Building* building);
public:
	Building()
	{
		this->m_bedRoom = "卧室";
		this->m_SittingRoom = "客厅";
	}


	//客厅 卧室
public:
	string m_SittingRoom;

private:
	string m_bedRoom;
};

void goodGay(Building* building)
{
	cout << "好基友正在访问 " << building->m_SittingRoom << endl;
	cout << "好基友正在访问 " << building->m_bedRoom << endl;
}

//友元函数的目的就是 访问类中的私有成员属性
void test01()
{
	Building* building = new Building;
	goodGay(building);

	delete building;
}

int main(void)
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

09 类做友元类

友元类注意:
1.友元关系不能被继承
2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

class Building
{
	//将全局函数变为 友元函数
	friend void goodGay(Building* building);
public:
	Building()
	{
		this->m_bedRoom = "卧室";
		this->m_SittingRoom = "客厅";
	}


	//客厅 卧室
public:
	string m_SittingRoom;

private:
	string m_bedRoom;
};

void goodGay(Building* building)
{
	cout << "好基友正在访问 " << building->m_SittingRoom << endl;
	cout << "好基友正在访问 " << building->m_bedRoom << endl;
}

//友元函数的目的就是 访问类中的私有成员属性
void test01()
{
	Building* building = new Building;
	goodGay(building);

	delete building;
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

在这里插入图片描述

10 成员函数做友元函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//只让visit可以作为Building的好朋友 ,visit2不可以访问私有成员属性
class Building;
class goodGay
{
public:
	goodGay();

	void visit();
	void visit2();
private:
	Building* m_building;

};
class Building
{
	//让成员函数 visit作为友元函数
	friend void goodGay::visit();
public:
	Building();

public:
	string m_SittingRoom;
private:
	string m_BedRoom;
};

void test01()
{
	goodGay gg;
	gg.visit();
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

Building::Building()
{
	this->m_BedRoom = "卧室";
	this->m_SittingRoom = "客厅";
}

goodGay::goodGay()
{
	this->m_building = new Building;
}

void goodGay::visit()
{
	cout << "好基友正在访问 " << m_building->m_SittingRoom << endl;
	cout << "好基友正在访问 " << m_building->m_BedRoom << endl;
}

void goodGay::visit2()
{
	cout << "好基友正在访问 " << m_building->m_SittingRoom << endl;
	//cout << "好基友正在访问 " << m_building->m_BedRoom << endl;
}

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:45:50  更:2022-08-19 18:50:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 21:49:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码