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;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值