C++学习 2018-11-28

本文深入探讨了C++中的虚函数、虚析构、纯虚函数等概念,讲解了如何通过虚函数实现多态,以及虚析构在防止内存泄漏中的作用。同时,介绍了静态成员变量和静态成员函数的定义与调用方式,讨论了头文件的正确使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++学习 2018-11-28

1.取得虚函数列表中的内容

CFather p1 = new CFather;
typedef void (PFUN)();
PFUN aa = (PFUN)
((int
)(int)p1 + 0);

#include <iostream>

using namespace std;

class CFather
{
public:
	virtual void AA()
	{
		cout << "CFather::AA()" << endl;
	}

	void BB()
	{
		cout << "CFather::BB()" << endl;
	}

	virtual void CC()
	{
		cout << "CFather::CC()" << endl;
	}
};

class CSon:public CFather
{
public:
	virtual void AA()
	{
		cout << "CSon::AA()" << endl;
	}

	void BB()
	{
		cout << "CSon::BB()" << endl;
	}

	virtual void CC()
	{
		cout << "CSon::CC()" << endl;
	}
	void DD()
	{
		cout << "CSon::DD()" << endl;
	}
};

int main()
{
	CFather *pp1 = new CSon;
	typedef void (*CFUN)();

	CFUN aa = (CFUN)*((int*)*(int*)pp1 + 0);
	CFUN bb = (CFUN)*((int*)*(int*)pp1 + 1);
	CFUN cc = (CFUN)*((int*)*(int*)pp1 + 2);
	// CFUN dd = (CFUN)*((int*)*(int*)pp1 + 3);

	bb();

	system("pause");
	return 0;
}

2.虚析构

语法:在析构函数前加上 virtual。

防止内存泄漏,通过父类的指针去删除一个子类的对象;为了在删除父类指针时也删除new出来的CSon对象(即调用CSon的析构函数)。

#include <iostream>

using namespace std;

class CFather
{
public:
	CFather()
	{
		cout << "CFather()" << endl;
	}

	/*~CFather()
	{
	cout << "~CFather()" << endl;
	}*/

	virtual ~CFather()
	{
		cout << "~CFather()" << endl;
	}
};


class CSon : public CFather
{
public:
	CSon()
	{
		cout << "CSon()" << endl;
	}

	virtual ~CSon()
	{
		cout << "~CSon()" << endl;
	}
};

int main()
{
	{
		// CFather *p1 = new CSon;
		// delete p1;
		// 由于当父类的析构函数不是虚函数时无法释放调用CSon的析构函数
		// 因此需要将父类的析构函数设置为虚函数

		CFather *p2 = new CSon;
		delete p2;
	}


	system("pause");
	return 0;
}

3.纯虚函数(抽象函数)

1.语法

virtual void Eat()=0;

2.包含纯虚函数的类称为抽象类。
3.抽象类不能定义对象。
4.纯虚函数强制有派生类,一定要重写。
5.抽象类的派生类称为具体类。
6.一个类的所有函数都是纯虚类,则这个类称为接口类。
#include <iostream>

using namespace std;

class CFather			// 抽象类(接口类)
{
public:
	virtual void ShowFather()=0;		// 纯虚函数

};

class CSon				// 具体类
{
public:
	virtual void ShowFather()
	{
		cout << "纯虚函数的重写" << endl;
	}
};

int main()
{
	CSon son;
	son.ShowFather();

	system("pause");
	return 0;
}

4.在类中定义一个静态成员变量

1.该静态成员变量在编译期存在。
2.调用方式: 类名::变量名 进行调用
3.必须在类外初始化

int CPerson::n_age = 100;

4.所有对象共享。
class CPerson
{
public:
	static int n_age;
};

int CPerson::n_age = 100;

int main()
{
	cout << CPerson::n_age << endl;

	system("pause");
	return 0;
}

5.在类中定义静态成员函数

1.静态函数不能使用非静态成员,可以使用静态成员变量。
class CPerson
{
public:
	static int n_static_age;
	int n_age;

public:
	static void StaticShow()
	{
		cout << n_static_age << endl;
		// cout << n_age << endl;		// 出错,无法调用非静态成员变量
	}
};

无法调用非静态成员变量的原因:没有this指针

2.静态函数不用对象就能够调用
class CPerson
{
public:
	static int n_static_age;
	int n_age;

public:
	static void StaticShow()
	{
		cout << n_static_age << endl;
		// cout << n_age << endl;		// 出错,无法调用非静态成员变量
	}
};

int main()
{
	CPerson::StaticShow();
	return 0;
}

6.头文件

1. .h 头文件中只放成员函数、成员属性的声明,静态成员变量的初始化放到同名cpp文件中。

.h头文件

class CPerson
{
public:
	int n_age;
	static int n_sex;
	const int n_name;

public:
	CPerson();
	~CPerson();

public:
	void AA();
	virtual void BB();
	void CC() const;
	static void DD();
};

cpp文件

#include "CPerson.h"
#include <iostream>

using namespace std;

CPerson::CPerson():n_sex(123)
{
	n_age = 100;
}

CPerson::~CPerson()
{
	cout << "~CPerson()" << endl;
}

void CPerson::AA()
{
	cout << "CPerson::AA" << endl;
}

void CPerson::BB()
{
	cout << "CPerson::BB" << endl;
}

void CPerson::CC() const
{
	cout << "CPerson::CC" << endl;
}

void CPerson::DD()
{
	cout << "CPerson::DD" << endl;
}

int CPerson::n_name = 200;
注意:在进行调试时需要另建一个cpp文件,其中需要包括main函数,若无main函数,则编译会出错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值