C++虚函数和多态

C++虚函数

C++类中用virtual修饰的函数 称之为虚函数

  • 虚函数对类的影响:让对象的内存增加4个字节(32操作系统)
  • 虚函数表:存放所有的虚函数

#include<iostream>
using namespace std;
class YXC {
public:
	// 虚函数
	virtual void print() {
		cout << "我是虚函数" << endl;
	}
	virtual void print2() {
		cout << "我也是虚函数" << endl;
	}
};
int main() {
	cout << sizeof(YXC) << endl;
	// 虚函数指针
	YXC yxc;
	long** p = (long**)& yxc;
	using pFunc = void(*)();
	pFunc pf = (pFunc)p[0][0];
	pf();
	pFunc pf2 = (pFunc)p[0][1];
	pf2();
	return 0;
}

C++虚函数和多态

多态指是同一行为的不同结果,大人,小孩坐车,一个免费一个需要收费

静态联编:函数重载

动态联编:C++类的多态

多态实现的前提条件

  • 父类必须存在和子类一致的函数,并且是虚函数
  • public继承才有多态
  • 必须存在指针引用
// 概念不重要,重要的是你要知道什么情况,该调用什么函数
#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
	virtual void print() {
		cout << "父类虚函数" << endl;
	}
	void printData() {
		cout << "父类普通函数" << endl;
	}
};
class XC : public YXC {
public:
	void print() {
		cout << "子类的print函数" << endl;
	}
	void printData() {
		cout << "子类的printData函数" << endl;
	}
private:
};
class A {
public:
	virtual void print() {
		cout << "A" << endl;
	}
};

class B :public A {
public:
	void print() {
		cout << "B" << endl;
	}
};

class C :public B {
public:
	void print() {
		cout << "C" << endl;
	}
};

int main() {
	// 1.正常对象 --->就近
	YXC yxc;
	XC xc;
	yxc.printData();
	yxc.print();
	xc.printData();
	xc.print();

	// 2.正常的指针 --->就近
	YXC* pYXC = new YXC;
	XC* pXc = new XC;
	pYXC->print();
	pYXC->printData();
	pXc->print();
	pXc->printData();

	// 3.不正常的赋值
	// 允许操作: 父类指针被子类的对象
	// 用多态的最终目的:用父类指针调用子类方法
	pYXC = new XC;
	pYXC->print();				// 有virtual 看对象
	pYXC->printData();			// 无virtual 看指针类型
	pYXC = new YXC;				// new
	pYXC->print();				// 多态
	pYXC = &xc;
	pYXC->print();				// 存在
	YXC& pRight = xc;			// 引用也算--->知道就行,千万别用
	pRight.print();
	// 虚函数被多层继承
	B* pB = new C;
	pB->print();
	A* pA = new C;			// 隔代了
	pA->print();
	pA->A::print();
	return 0;
}

在这里插入图片描述

C++纯虚函数和ADT

  • 纯虚函数是没有函数体的虚函数,纯虚函数也是虚函数
    • virtual 函数返回值类型 函数名(参数)=0;
  • 具有纯虚函数的类叫做抽象
    • 抽象类没有办法构建对象
    • 抽象类可以构建对象指针
#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
	YXC(string name,int age):name(name),age(age){}
	virtual void print() = 0;
protected:
	string name;
	int age;
};
class XC : public YXC {
public:
	XC() :YXC("易小川",18){}
	// 重写概念:
	void print() {
		cout << "XC重写print" << endl;
	}
protected:
};
// ADT  : 抽象数据类型
//
class StuSystem {
public:
	virtual void insertData() = 0;
	virtual void deleteData() = 0;
	virtual void showData() const = 0;
	virtual int size() const = 0;
	virtual int empty() const = 0;
protected:
};
class listSystem :public StuSystem {
public:
	void insertData(){}
	void deleteData(){}
	void showData() const{}
	int size() const { return 0; }
	int empty() const { return 0; }
protected:
};
void testData() {
	StuSystem* ps = new listSystem;
	ps->insertData();
	ps->insertData();
	ps->showData();
}

int main() {
	 //	YXC xc;  // 抽象类不能构建对象
	YXC* pYXC = nullptr;
	pYXC = new XC;
	pYXC->print();
	testData();
	return 0;
}

在这里插入图片描述

C++虚析构函数

析构函数用virtual 修饰就是虚析构函数

存在子类指针被子类对象初始化的情况,通常大家要写虚析构函数

#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
	 ~YXC() // 父类用虚析构函数
	{
		cout << "MM" << endl;
	}
};
class XC :public YXC {
public:
	~XC() {
		cout << "XC" << endl;
	}
};
int main() {
	{
		YXC* pYxc = new XC;
		delete pYxc;
	}
	return 0;
}

C++内联思想

当前函数编译后 二进制的形式存在,以牺牲空间的方式提高效率,内联函数的特点,一定是短小精悍

  • C++中用inline修饰的函数
  • 类中实现的函数默认为内联
#include<iostream>
using namespace std;
inline int Max(int a, int b) {
	return a > b ? a : b;
}
class YXC {
public:
	void print() {
		cout << "默认为内联函数" << endl;
	}
	inline void printData();
};
void YXC::printData() {
	cout << "类外实现" << endl;
}
int main() {
	YXC yxc;
	yxc.print();
	yxc.printData();
	return 0;
}

C++结构体

C++类中能干的事情,结构体可以干

  • 构造函数
  • 继承
  • 多态
  • 重写
  • 重载

C++结构体默认属性是public,类中默认属性是private属性

// 业余选手可以这样搞,专业选手不这样做,因为低耦合,高内聚的追求
#include<iostream>
#include<string>
using namespace std;
struct YXC {
	string name;
	int age;
	void print() {
		cout << name << "\t" << age << endl;
	}
};

struct XC {
	string name;
	int age;
	XC(string name,int age):name(name),age(age){}
	void print() {
		cout << this->name << "\t" << this->age << endl;
	}
};

struct YXG {
protected:
	string name;
	int age;
public:
	YXG(string name, int age) :name(name), age(age) {}
public:
	void print() {
		cout << this->name << "\t" << this->age << endl;
	}
};

struct XG : public YXG {
	XG() :YXG("YXG",16){}
	~XG() {
		cout << "析构函数" << endl;
	}
};

int main() {
	YXC yxc = { "name",18 }; // 没有写构造函数,跟C语言语法一模一样的
	yxc.print();
	XC xc = { "name",18 };		// 一旦写了构造函数 , 当类使用
	cout << xc.name << "\t" << xc.age << endl;
	YXG yxg("YXG", 20);
	yxg.print();
	XG xg;
	xg.print();
	return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值