关于C++虚函数,纯虚函数以及模板等重要概念的深入讨论(二)



2.析构与虚析构函数

  为了说明基类的析构函数必须为虚析构函数,我们来实践一下:在A的析构函数中加入输出cout << "This is A class." << endl;同理在B的析构函数中也加入输出cout << "This is B class." << endl;

最后在main函数objectC->print();下方加入语句:delete objectC; objectC = NULL;从而销毁对象,调用析构函数。如果基类A的析构函数非虚析构的话,运行结果如下:

        

如果将基类A的析构函数改写为虚析构函数:virtual ~A();那么运行的结果如下:

        

    可以清晰的看到,在基类A中如果是非虚析构函数时,销毁objectC 对象的时候则没有调用B析构函数,而若为虚析构函数的话,就会调用B的析构函数。因此为了防止释放指向子类的基类指针时,子类发生内存泄露现象,我们必须将基类的析构函数设置为虚析构!

3.虚函数与纯虚函数

    虚函数即是在声明函数的时候在前面加入virtual 关键字如:virtual void print(); 而纯虚函数则是这样定义的:virtual void print() = 0; 即纯虚函数没有实体,实体是需要它的继承重写来实现的。我们来看一段实例代码:

// Test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream"
using namespace std;

class C
{
	virtual void draw1(){};
	virtual void draw2() = 0;
};
class A
{
private:
	int valueA;
public:
	A();
	A(int value);
	virtual ~A();
	virtual void print(int value);
};
//The class A realize.
A::A()
{
	valueA = 0;
}
A::A(int value)
{
	valueA = value;
}
A::~A()
{
	cout << "This is A class." << endl;
}
void A::print(int value)
{
	cout << "This is A print and Value is :" << value <<endl;
}

class B:public A, public C
{
private:
	int valueB;
public:
	B();
	B(int value);
	~B();
        void print(int value);
	void draw2();
};
//The class B realize.
B::B()
{
	valueB = 0;
}
B::B(int value):A(value)
{
	valueB = value;
}
B::~B()
{
	cout << "This is B class." << endl;
}
void B::print(int value)
{
	cout << "This is B print and Value is :" << value << endl;
}
void B::draw2()
{
	cout << "This is B draw and Value is :" << valueB << endl;
}
int main(void)
{
	A *objectA = new A(10);
	B *objectB = new B(20);
	A *objectC = objectB;

	objectA->print(1);
	objectB->print(2);
	objectC->print(3);
	delete objectC;
	objectC = NULL;
	return 0;
}

在上述的代码中我们新加入了一个类C,它里面包含了一个虚函数draw1,以及一个纯虚函数draw2;然后我们让B继承这个类,并且在B类中我们重写了draw2函数,如果不重写那么会出现以下错误:

        

    编译器告诉我们必须要重写draw2函数,这样程序就能顺利的运行了;我们把带有虚函数的类称为抽象类,即上述实例中C就为抽象类,抽象类的特点是:它没有实体,我们不能把抽象类给实例化,即不能定义一个抽象类的对象;感兴趣的同学可以试一下,编译器会报错的不能实例化抽象类。

    既然抽象类不能被实例化,而且他的纯虚成员函数还必须被继承它的子类继承,那么这种结构有什么用呢?答案是,它可以实现很好的扩展,在大型软件的编写过程中抽象类和纯虚函数会经常的用到,如果你看设计模式的话,可以看到有很多的设计模式中会用到抽象类和纯虚函数,它可以实现一种接口的作用,其实如果抽象类中只有纯虚函数这一种结构,那么它跟C#以及java等语言中的接口(也有人叫协议)的概念是一样的,最新式的用于Iphone开发的Swift语言就大量的使用接口,所以人们习惯叫这种新式的语言为面向协议的语言。可见抽象类和纯虚函数是有多么的强大。建议大家如何对它们感兴趣的话,一定要看看设计模式,你会有很大的收获!


<未完待续>



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值