day9.C++多态之虚函数

C++多态之虚函数

1)什么是虚函数

多态性主要通过虚函数(virtual functions)实现,它允许派⽣类重写基类中的⽅

法,从⽽在运⾏时根据对象的实际类型来调⽤相应的函数。

实现原理

c++ 复制代码
#include<iostream> 
#include<string>

using namespace std;



class animal
{
   public:
	virtual void runing()
	{
		
		cout<<"i can run"<<endl;
	}
	
	virtual void talk()
	{
		cout<<" i can talk"<<endl;
	}
	
	
};


//派生类继承了父类,父类中的虚函数 在派生类即使被重写了,该函数仍然是虚函数。
class cat :public animal
{
public:
	virtual void runing() // 派生类中对父类的虚函数进行重新实现,该函数不管加不加virtal关键字修饰,它都是虚函数,一般建议加上。
	{
		cout<<" i can run fast"<<endl;
		
	}
	
	//重写:在派生类中对父类的同名成员函数 进行重新实现, 重载:在同一个作用域下,编写多个同名函数,要确保这些函数要么形参或类型不一样
	virtual void talk()
	{
		cout<<" i can talk by cat language"<<endl;
	}
	
};

class dog :public animal
{
public:
	//在派生类重写父类中虚函数时 加上是一个好习惯。
	virtual void runing() override  //如果派生类中重写的成员函数如果加了这个关键字override修饰,在编译的时候 它会自动取检测父类是否存在该虚函数 如果不存在就报错,如果存在则放行
	{
		cout<<" i can run and jump"<<endl;
		
	}
	
	virtual void talk()override
	{
		cout<<" i can talk by dog language"<<endl;
	}
	
	
};


void test(animal &per) //动态多态是建立在继承的基础之上,没有继承就没有多态。
{
	
	per.runing();
	//per.talk();
	
}


//实现多态的条件:1.需要在基类中定义虚函数 2.在派生类中对父类的虚函数实现重写 3.多态的接口需要用父类的指针或父类的引用类型  4.派生类需要采用公有继承

int main() {

	
	cat s1;
	dog s2;
	
	test(s1);
	test(s2);
	
	/*
	
	不同对象s1,s2 调用相同接口runing()所表现出的不同行为
	i can run fast
	i can run and jump 
	 这个就叫做多态
	*/
	
	return 0;
}
c++ 复制代码
#include<iostream> 
#include<string>

using namespace std;

class bird
{
public:
	virtual void fly() final  //final修饰父类的虚函数,就表示该成员函数不允许在派生类中得到重写。final关键字可以阻断派生类对它所修饰的虚函数进行重写
	{
		
		
		cout<<" i can flying"<<endl;
	}
	
	
	
};

class tuo_bird:public bird
{
public:
//	virtual void fly() 
//	{
//		
//		
//	}
	
	
	
};




int main() {

	
	tuo_bird s1;
	//s1.fly();
	s1.fly();
	

	
	return 0;
}
c++ 复制代码
#include<iostream> 
#include<string>

using namespace std;

class bird
{
public:
	//纯虚函数的定义格式:virtual 返回类型 函数名([形参列表])=0;  特点:它是一个没有函数体的函数,靠派生类来实现
	//抽象类:如果一个类中存在纯虚函数,那么该类就变成了 抽象类
	//抽象类特点:不可以通过抽象类构建对象
	virtual void fly()=0;
	//virtual void myfly()=0;
	
	
	
};

class parrot:public bird  //如果派生类继承了抽象类 如果在派生类中没有对父类中的纯虚函数进行重写,那么该派生类也是抽象类
{
	
public:
	void fly()  //派生类但凡对父类中的任何一个纯虚没有实现 派生类仍然是抽象类
	{
		
		cout<<" i can fly";
	}
	
	
	
};






int main() {


   parrot ss;
   cout<<sizeof(ss);//8 ---一个类中存在虚函数,会造成该类创建的对象 会多占用对象一个指针大小的空间。
	
	return 0;
}
c++ 复制代码
#include<iostream> 
#include<string>

using namespace std;

class bird
{
public:

	virtual void fly()
	{
		cout<<"fly from bird";
	}
	
	virtual ~ bird()
	{
		
		cout<<"bird 析构函数"<<endl;
	}

	
	
};

class parrot:public bird  //如果派生类继承了抽象类 如果在派生类中没有对父类中的纯虚函数进行重写,那么该派生类也是抽象类
{
	
public:
	void fly()  //派生类但凡对父类中的任何一个纯虚没有实现 派生类仍然是抽象类
	{
		
		cout<<" i can fly";
	}
	
	~parrot()
	{
		
		cout<<"parrot"<<endl;
	}
	
	
	
};






int main() {


 //当用父类的指针指向一个派生类对象时,此时 如何对该地址施加一个delete 会造成内存泄漏。
  bird * s1=new parrot;
	
  delete s1;
	
	return 0;
}

菱形继承

c++ 复制代码
#include<iostream> 
#include<string>

using namespace std;


//菱形继承:会造成最底层的派生类保存两份最上层类的数据成员,从而造成数据冗余和内容浪费,采用虚继承。virtual可以用来修饰类中的成员函数,也可以修饰继承方式
class A
{
public:
	//int a;
    double arr[5];

	
	
};


class B:  virtual public A
{
public:
	int b;

	
	
};


class C :  virtual public A
{
public:
	int c;

	
	
};


class D: public B,  public C
{
//public:
//	int d;

};


int main() {

	D dd;
	cout<<sizeof(dd);//通过虚继承 可以让最底层类 只保留一份最上层类的数据成员,但是我们也付出了代码,也要维护指针占用的空间。

	return 0;
}
相关推荐
码云数智-园园1 小时前
类似小鹅通的知识付费小程序平台有哪些
开发语言
Darkwanderor1 小时前
Linux线程控制
linux·c语言·c++
snow@li1 小时前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
Livia要学习1 小时前
Python闭包
开发语言·jvm·python
覆东流1 小时前
2.Java程序基础
java·开发语言·后端
ttwuai1 小时前
Go 后台定时任务启停不生效怎么办?先查调度同步链路
开发语言·后端·golang
小的~~2 小时前
ThreadLocal 、InheritableThreadLocal 与 TransmittableThreadLocal 的进阶指南
java·开发语言
Darkwanderor2 小时前
多线程的互斥问题和互斥锁解决互斥问题
linux·c语言·c++
键盘会跳舞2 小时前
C++:std::pair 源码级深度剖析 —— 关联容器的基石
开发语言·c++·pair·关联容器