03 类中的特殊成员

类中的一些特殊情况

学习目的

掌握类中的特殊成员(变量 & 函数)

掌握友元关系(**)

掌握单例模式

1. this指针

this 指针是系统自动生成,且隐藏的;

this 不是对象的一部分,作用域在类的内部;

类的普通函数访问类的普通成员时,this 指针总是指向所调用的对象。

类中对象与成员的关系

普通数据成员,每个对象都有单独的一份,成员函数整个类都只有一份,多个对象共用。

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

class MyClass
{
public:
	void	setNum(int n);
	int		getNum();
private:
	int num;
};

void MyClass::setNum(int num)
{
	// 如何在类的成员函数里面区分 自己的数据成员 以及同名的参数?
	// 使用 this 指针!
	num = num;
}
int MyClass::getNum()
{
	return num;
}


int	main()
{
	MyClass obj_0;
	obj_0.setNum(10);
	cout << "num = " << obj_0.getNum() << endl;


	return 0;
}

this指针:

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

class MyClass
{
public:
	void	setNum(int n);
	int		getNum();
private:
	int num;
};

void MyClass::setNum(int num)
{
	// 如何在类的成员函数里面区分 自己的数据成员 以及同名的参数?
	// 使用 this 指针!
	this->num = num;
}
int MyClass::getNum()
{
	return num;
}


int	main()
{
	MyClass obj_0;
	obj_0.setNum(10);
	cout << "num = " << obj_0.getNum() << endl;


	return 0;
}

如果成员函数的参数与成员变量参数不重名,则不需要使用this指针,

否则必须使用this指针。

2. static成员(**)

在C++类中声明成员时,加上 static 关键字;

静态成员分为静态数据成员静态函数成员

静态成员可直接通过类名访问。

静态数据成员

给静态数据成员初始化时需在类外进行,不能再构造函数中初始化。

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

class ClassName
{
public:
	ClassName();
	~ClassName();

	static int num;

};
int ClassName::num = 0;

ClassName::ClassName()
{
}

ClassName::~ClassName()
{
}

int	main()
{
	//ClassName obj_0;
	//cout << "num = " << obj_0.num << endl;

	return 0;
}

特点:

  1. 类中所有对象全部共享着同一段静态数据成员的内存(图中篮框);

    在这里插入图片描述

验证:

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

class ClassName
{
public:
	ClassName();
	~ClassName();

	static int num;

};
int ClassName::num = 0;

ClassName::ClassName()
{
}

ClassName::~ClassName()
{
}

int	main()
{
	ClassName obj_0;
	cout << "obj_0.num = " << obj_0.num << endl;
	obj_0.num = 5;
	ClassName obj_1;
	cout << "obj_1.num = " << obj_1.num << endl;


	return 0;
}

静态数据成员在类创建之前就已经有了,生命周期比类长(比任何一个对象都长),属于整个类不属于任何一个对象,因此可以通过类名+作用域符访问

ClassName::num;

静态成员函数

静态成员函数不能访问普通数据成员(非静态变量),也无法调用普通成员函数,也无法使用this指针。

用例:

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

class ClassName
{
public:
	ClassName();
	~ClassName();

	static int num;

	static void testFunc_1();

	static void testFunc_2()
	{
		cout << " ClassName::testFunc_2()" << endl;
	}

};
int ClassName::num = 0;

void ClassName::testFunc_1()
{
	cout << " ClassName::testFunc_1()" << endl;
}

ClassName::ClassName()
{
	num++;
}

ClassName::~ClassName()
{
}

int	main()
{
	ClassName obj_0;
	cout << "obj_0.num = " << obj_0.num << endl;
	//obj_0.num = 5;
	ClassName obj_1;
	cout << "obj_1.num = " << obj_1.num << endl;

	// 对象成员访问
	obj_1.testFunc_1();
	// 指针访问
	ClassName* p = &obj_0;
	p->testFunc_2();
	// 类名访问
	ClassName::testFunc_1();
	ClassName::testFunc_2();

	return 0;
}

单例模式:设计模式(解决一类问题的通用方法)

创建一个只能实例化一个对象的类(但是可以多个指针指向它)

单例举例:

#include <iostream>
using namespace std;
// 单例模式:创建一个只能实例一个对象的类
// 从构造函数的角度上限制

class SingleInstance
{
public:
	~SingleInstance();
	static SingleInstance* getInstance();

private:
	SingleInstance();
	SingleInstance(const SingleInstance& obj);
	static	SingleInstance* pInstance;
	
public:
	int num;

};
SingleInstance* SingleInstance::pInstance = NULL;

SingleInstance::SingleInstance()
{
	num = 0;
}

SingleInstance::SingleInstance(const SingleInstance& obj)
{
}

SingleInstance* SingleInstance::getInstance()
{
	if (pInstance == NULL)
	{
		pInstance = new SingleInstance;
	}
	return pInstance;	
}
SingleInstance::~SingleInstance()
{
}

int main()
{
	SingleInstance* p1 = SingleInstance::getInstance();
	cout << "num = " << p1->num << endl;
	SingleInstance* p2 = SingleInstance::getInstance();
	p2->num = 99;
	SingleInstance* p3 = SingleInstance::getInstance();
	cout << "num = " << p3->num << endl;

	cout << hex << p1 << endl;
	cout << hex << p2 << endl;
	cout << hex << p3 << endl;


	return 0;
}

3. const 成员

在C++类中声明对象时加上 const 关键字,常量成员分为常量数据成员常量函数成员

常量数据成员

#include <iostream>
using namespace std;

class ClassName
{
public:
	ClassName();
	ClassName(int v);
	ClassName(int v,int num);
	~ClassName();

	int num;
	const int val;

};

ClassName::ClassName() : val(0)
{
	num = 0;
}
ClassName::ClassName(int v) : val(v)
{
	num = v;
}
// 使用成员初始化列表对非静态成员初始化
ClassName::ClassName(int v, int num) : val(v), num(num)
{
}

ClassName::~ClassName()
{
}


int main()
{
	ClassName obj_1;
	cout << "obj_1.val = " << obj_1.val << endl;
	ClassName obj_2;
	cout << "obj_2.val = " << obj_2.val << endl;

	ClassName obj_3(6);
	cout << "obj_3.val = " << obj_3.val << endl;
	ClassName obj_4(7, 8);
	cout << "obj_3.val = " << obj_3.val << endl;
	cout << "obj_4.val = " << obj_4.val << "		" << "obj_4.num = " << obj_4.num << endl;


	return 0;
}

常量成员函数

类外实现常量成员函数时,const 关键字不能丢掉(const 属于成员函数的一部分,定义和实现都需要加在()后面。)

#include <iostream>
using namespace std;

class ClassName
{
public:
	ClassName();
	ClassName(int v);
	ClassName(int v,int num);
	~ClassName();

	int num;
	const int val;

	void testFunc_1();
	// 常成员函数声明
	void testFunc_2() const;

};

ClassName::ClassName() : val(0)
{
	num = 0;
}
ClassName::ClassName(int v) : val(v)
{
	this->num = v;
}
// 使用成员初始化列表对非静态成员初始化
ClassName::ClassName(int v, int num) : val(v), num(num)
{
}
// 普通成员函数定义
void ClassName::testFunc_1()
{
	cout << "test_Func_1()" << endl;
	cout << "val = " << this->val << endl;
	cout << "num = " << this->num << endl;
}
// 常成员函数定义
void ClassName::testFunc_2() const
{
	cout << "test_Func_2()" << endl;
	cout << "val = " << this->val << endl;
	cout << "num = " << this->num << endl;
}
ClassName::~ClassName()
{
}


int main()
{
	ClassName obj_1;
	cout << "obj_1.val = " << obj_1.val << endl;
	ClassName obj_2;
	cout << "obj_2.val = " << obj_2.val << endl;

	ClassName obj_3(6);
	cout << "obj_3.val = " << obj_3.val << endl;
	ClassName obj_4(9, 8);
	obj_4.testFunc_1();
	obj_4.testFunc_2();


	return 0;
}

const 成员函数的意义:常量成员函数不能对类里面的任何数据成员进行修改(只能访问,不能修改。)但是,可以修改静态数据成员。

常对象

常对象只能调用常成员函数(也不能修改常成员变量)静态成员

#include <iostream>
using namespace std;

class ClassName
{
public:
	ClassName();
	ClassName(int v);
	ClassName(int v,int num);
	~ClassName();

	int num;
	const int val;

	void testFunc_1();
	// 常成员函数声明
	void testFunc_2() const;
	static int n;

};
int ClassName::n = 0;


ClassName::ClassName() : val(0)
{
	num = 0;
}
ClassName::ClassName(int v) : val(v)
{
	this->num = v;
}
// 使用成员初始化列表对非静态成员初始化
ClassName::ClassName(int v, int num) : val(v), num(num)
{
}
// 普通成员函数定义
void ClassName::testFunc_1()
{
	cout << "test_Func_1()" << endl;
	cout << "val = " << this->val << endl;
	cout << "num = " << this->num << endl;
}
// 常成员函数定义
void ClassName::testFunc_2() const
{
	cout << "test_Func_2()" << endl;
	cout << "val = " << this->val << endl;
	cout << "num = " << this->num << endl;
}
ClassName::~ClassName()
{
}


int main()
{
	ClassName obj_1;
	cout << "obj_1.val = " << obj_1.val << endl;
	ClassName obj_2;
	cout << "obj_2.val = " << obj_2.val << endl;

	ClassName obj_3(6);
	cout << "obj_3.val = " << obj_3.val << endl;
	ClassName obj_4(9, 8);
	obj_4.testFunc_1();
	obj_4.testFunc_2();

	const ClassName obj_5(3, 4);
	// obj_5.num = 2;	// 常对象不能修改普通成员变量,可以修改静态成员变量(静态成员变量不属于单独的某一个对象)
	obj_5.n = 7;
	// obj_5.test_func_1();	// 常对象也不能调用普通成员函数(普通成员函数有修改数据成员的权限)。
	obj_5.testFunc_2();		// 常对象只能调用常成员函数 或 静态成员。

	ClassName const obj_6(3,4);
	//obj_6.num = 2;
	obj_6.n = 9;


	return 0;
}

4. 友元关系:friend(**)

类的特性之一是封装(private),友元是打破封装的手段。

友元分为友元函数和友元类;

友元类可以创建友元对象。

友元函数

#include <iostream>
using namespace std;

class A
{
	int num;
	friend void testFunc_1(A obj);
public:
	A()
	{
		this->num = 1;
	}
};

void testFunc_1(A obj)
{
	obj.num = 0;
}

int main()
{
	A a;
	testFunc_1(a);

	return 0;
}

友元类

#include <iostream>
using namespace std;

class A
{
	int num;
	friend class B;
};

class B
{
public:
	void testFunc(A obj)
	{
		obj.num;
	}
};

int main()
{


	return 0;
}

特点:单方向、不具有传递性、不继承。


<未完待续>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值