【C语言教程】纯虚函数的实例详解

所需工具:

C++

聪明的大脑

勤劳的双手

 

注意:本站只提供教程,不提供任何成品+工具+软件链接,仅限用于学习和研究,禁止商业用途,未经允许禁止转载/分享等

 

教程如下

虚函数和纯虚函数

之前学过虚函数,语法:virtual 返回值类型 函数名(参数列表),然后这个类也就变成的虚基类,然后子类重写父类的虚函数。

纯虚函数,语法:virtual 返回值类型 函数名(参数列表)=0,当类中有了纯虚函数,这个类也称为抽象类。抽象类特点:无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类。

 	class Base
 	{
 	public:
 	     virtual void Examp() = 0;//纯虚函数
 	     ~Base()
 	     {
 	         cout << "父类的析构函数" << endl;
 	     }
 	};
 	
 	class Son:public Base
 	{
 	public:
 	     void Examp()
 	     {
 	         cout << "重写了父类的纯虚函数" << endl;
 	     }
 	
 	     ~Son()
 	     {
 	         cout << "子类的析构函数" << endl;
 	     }
 	};
 	
 	int main()
 	{
 	     Son p1;
 	     p1.Examp();
 	     system("pause");
 	}

上面是最简单的纯虚函数代码,子类必须得重写重写抽象类中的纯虚函数,不然不能实例化对象。

接下来我们如果利用子类对象开辟堆区,那么会带来父类指针释放子类对象时不干净的问题,即子类的析构函数不能够正常的被调用,会带来内存泄漏的问题:

 	int main()
 	{
 	     Son *p1=new Son;//子类对象开辟堆区
 	     p1->Examp();
 	     delete p1;//释放堆区,自动调用析构函数
 	     system("pause");
 	}

为了解决这个问题,可以利用虚析构和纯虚析构,也很简单,直接在父类的析构函数前面加上virtual关键字就成为了虚析构函数,这个类也会成为抽象类。

 	class Base
 	{
 	public:
 	     virtual void Examp() = 0;//纯虚函数
 	     virtual ~Base()//虚析构
 	     {
 	         cout << "父类的析构函数" << endl;
 	     }
 	};

或者是利用纯虚析构

 	class Base
 	{
 	public:
 	     virtual void Examp() = 0;//纯虚函数
 	
 	     virtual ~Base() = 0;//类内声明
 	};
 	
 	Base::~Base()//类外实现
 	{
 	         cout << "父类的析构函数" << endl;
 	}

附:纯虚函数的应用

包含纯虚函数的类叫抽象类,它不能生成对象,用户不能创建类的实例,只能创建派生类的实例。

注明:纯虚函数必须在继承类中重新声明函数(去掉后面的0,否则该派生类也不能实例化)。就是基类告诉子类,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它。”

代码实现:

 	include<stdio.h>
 	#include<iostream>
 	using namespace std;
 	class Base
 	{
 	public:
 	         virtual void func()=0; //在基类中声明纯虚函数
 	};
 	class Derived:public Base
 	{
 	public:
 	         void func() //在子类中重写纯虚函数
 	         {
 	                 cout<<"哈哈"<<endl;
 	         }
 	};
 	int main()
 	{
 	         Base *b=new Derived(); //基类的指针调用子类重写的纯虚函数
 	         b->func();
 	         return 0;
 	}

总结

虚析构或纯虚析构就是用来解决通过父类指针释放子类对象

如果子类中没有堆区数据,可以不写为虚析构或纯虚析构tImage();

//定义方向键的标志
boolean up,down,left,right;

public HeroPlane() {
}

public HeroPlane(int x, int y, int width, int heigth, Image img) {
this.x = x;
this.y = y;
this.width = width;
this.heigth = heigth;
}

@Override
public void run() {
while (true){
if (up){
y -= speed;
}
if (down){
y += speed;
}
if (left){
x -= speed;
}
if (right){
x += speed;
}

try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
[/php]

Player

 	package cn.tx;
 	import java.awt.event.KeyAdapter;
 	import java.awt.event.KeyEvent;
 	//定义一个玩家
 	public class Player extends KeyAdapter {
 	     GameFrame frame;
 	     HeroPlane heroPlane;
 	     public Player(GameFrame frame) {
 	     this.frame=frame;
 	     }
 	 
 	     public void keyPressed(KeyEvent e) {
 	     int keyCode = e.getKeyCode();
 	     //38、40、37、39
 	     switch (keyCode){
 	         case 38:
 	         frame.heroPlane.up = true;
 	         break;
 	         case 40:
 	         frame. heroPlane.down = true;
 	         break;
 	         case 37:
 	         frame. heroPlane.left = true;
 	         break;
 	         case 39:
 	         frame. heroPlane.right = true;
 	         break;
 	         case 66:
 	         addBullut();
 	         break;
 	     }
 	 
 	     }
 	 
 	     @Override
 	     public void keyReleased(KeyEvent e) {
 	     int keyCode = e.getKeyCode();
 	     //38、40、37、39
 	     switch (keyCode){
 	         case 38:
 	         frame.heroPlane.up = false;
 	         break;
 	         case 40:
 	         frame. heroPlane.down = false;
 	         break;
 	         case 37:
 	         frame. heroPlane.left = false;
 	         break;
 	         case 39:
 	         frame. heroPlane.right = false;
 	         break;
 	     }
 	     }
 	     public void addBullut(){
 	     frame.bullets.add(new Bullet( frame.heroPlane.x+5, frame.heroPlane.y - 20));
 	     }
 	}

EnemyPlane

 	package cn.tx;
 	 
 	import javax.swing.*;
 	import java.awt.*;
 	 
 	 
 	public class EnemyPlane extends Thread {
 	     public GameFrame gf;
 	     //子弹的坐标,大小速度
 	     public int x, y;
 	     public int width = 50;
 	     public int heigth = 50;
 	     public int speed = 2;
 	     public Image img = new ImageIcon("img/10021.png").getImage();
 	 
 	     public EnemyPlane(int x, int y, GameFrame gf) {
 	     super();
 	     this.x = x;
 	     this.y = y;
 	     this.gf = gf;
 	     }
 	 
 	     public EnemyPlane(int x, int y, int width, int heigth, GameFrame gf) {
 	     super();
 	     this.x = x;
 	     this.y = y;
 	     this.width = width;
 	     this.heigth = heigth;
 	     this.gf = gf;
 	     }
 	 
 	     //玛丽飞翔的逻辑;移动的逻辑都在这里。
 	     public void run() {
 	     while (true) {
 	         //向左走
 	         if (hit()) {
 	         System.out.println("hit................");
 	         this.speed = 0;
 	         this.img = new ImageIcon("img/300350.png").getImage();
 	             try {
 	             this.sleep(500);
 	             } catch (InterruptedException e) {
 	             e.printStackTrace();
 	             }
 	             gf.enemys.remove(this);
 	             break;
 	         }
 	         if (this.y >= 760) {
 	             break;
 	         }
 	         try {
 	             this.sleep(10);
 	         } catch (InterruptedException e) {
 	             e.printStackTrace();
 	         }
 	     }
 	     }
 	 
 	 
 	     //检测碰撞
 	     public boolean hit() {
 	     // swing在水中,人家已经提供了
 	     Rectangle myrect = new Rectangle(this.x, this.y, this.width, this.heigth);
 	     Rectangle rect = null;
 	     for (int i = 0; 1 < gf.bullets.size(); i++) {
 	         Bullet bullet = gf.bullets.get(i);
 	         System.out.println("test hit");
 	         rect = new Rectangle(bullet.x, bullet.y - 1, bullet.width, bullet.height);
 	         //碰撞检测
 	         if (myrect.intersects(rect)) {
 	         return true;
 	         }
 	     }
 	     return false;
 	     }
 	 
 	     @Override
 	     public String toString() {
 	     return "EnemyPlane{" +
 	         "x=" + x +
 	         ", y=" + y +
 	         ", width=" + width +
 	         ", height=" + heigth +
 	         '}';
 	     }
 	}

Bullet

 	package cn.tx;
 	import javax.swing.*;
 	import java.awt.*;
 	 
 	public class Bullet {
 	     //在面板上的坐标
 	     int x, y;
 	     int width= 50,height = 50;
 	 
 	     //定义飞机默认速度
 	     int speed = 5;
 	 
 	     Image image = new ImageIcon("img/30022.png").getImage();
 	 
 	     public Bullet(int x, int y) {
 	     this.x = x;
 	     this.y = y;
 	     }
 	 
 	     public Bullet(int x, int y, int width, int height) {
 	     this.x = x;
 	     this.y = y;
 	     this.width = width;
 	     this.height = height;
 	     }
 	}

 

 

标签

发表评论