纯虚函数、虚析构

----纯虚函数的声明:  virtual  函数声明 = 0
1.只有声明,没有实现体  = 0仅仅只是语法表现形式
2.含有纯虚函数的类 叫抽象基类  不能实例化(不能生成对象)
3.仅仅是为了提供族类的接口 java 中 称此种类为 Interface
4.如果子类中没有覆写纯虚函数,那子类也为抽象基类 也不能实例化
5.
如果子类只是把父类的纯虚函数原封不动拿到内部声明,语法也通不过,拿下来就必须覆写,要不然就不拿(最新版本的c++支持把父类的纯虚函数原封不动拿到内部声明)

----析构函数声明为virtual(虚析构):
继承时,要养成的一个好习惯就是,基类析构函数中,加上virtual

使用情况:
        即使没有虚函数的类,也可能产生父类指针指向子类对象的情况(多态),在这种情况下,父类的析构函数要声明为虚析构凡是含有虚函数的类,析构函数也应该声明为虚函数,才可以实现完整的析构。delete 父类的指针,要实现同时调用父子类的析构,不虚的话只调用了父类的析构函数。

原因
       可以将子类对象的地址赋值给父类指针,也就是说父类指针可以指向子类的对象(多态性),如果删除该父类指针delete []p;就会调用该指针指向的子类析构函数,而子类的析构函数又自动调用父类的析构函数,这样整个派生类的对象完全被释放。
如果父类的析构函数不被声明成虚函数,则编译器实施静态绑定虚函数是动态绑定的基础,因此现在不会发生动态绑定,指针的类型为父类指针,在删除父类指针时,只会调用父类的析构函数而不调用子类析构函数,这样就会造成子类对象析构不完全。造成内存泄漏,所以,将析构函数声明为虚函数是十分必要的。
其他文章:https://www.cnblogs.com/liushui-sky/p/5824919.html

----成为虚函数的限制:
1)只有类的成员函数才能声明为虚函数,虚函数仅适用于有继承关系的类对象,所以普通函数不能声明为虚函数。
2)静态成员函数不能是虚函数,静态成员函数不受对象的捆绑,只有类的信息。
3)内联函数不能是虚函数
4)构造函数不能是虚函数,构造时,对象的创建尚未完成。构造完成后,才能算一个名符其实的对象。构造函数同时承担着虚函数表的建立,没有对象的时候,虚函数没有意义
5)析构函数可以是虚函数且通常声明为虚函数

主函数:

#include "stdafx.h"
#include <iostream>
using namespace std;
#include "Dog.h"
#include "Cat.h"


int _tmain(int argc, _TCHAR* argv[])
{
	//Dog g;
	g.voice();

	//Cat c;
	c.voice();

	//Animal *pa = &g;
	//pa->voice();

	//pa = &c;
	//pa->voice();

	//Animal a; 抽象基类不能实例化

	cout << "==================" << endl;

	Animal* p = new Dog;
	p->voice();
	delete p;

	//p = new Cat;
	//p->voice();

	return 0;
}

 

Animal.h

#pragma once
#include <iostream>
using namespace std;


class Animal
{
public:
	Animal();
	virtual ~Animal(); //需要加virtual实现完整的析构

	virtual void voice() = 0; //纯虚函数
};

 

Animal.cpp

#include "Animal.h"


Animal::Animal()
{
	cout << "Animal::Animal()" << endl;
}


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

 

Dog.h

#pragma once
#include <iostream>
using namespace std;
#include "Animal.h"


class Dog:public Animal
{
public:
	Dog();
	virtual ~Dog();

	virtual void voice();
};

 

Dog.cpp

#include "Dog.h"


Dog::Dog()
{
	cout << "Dog::Dog()" << endl;
}


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

void Dog::voice()
{
	cout << " wang wang wang wang " << endl;
}

 

Cat.h

#pragma once
#include <iostream>
using namespace std;
#include "Animal.h"


class Cat:public Animal
{
public:
	Cat();
	virtual ~Cat();

	virtual void voice();
};

 

Cat.cpp

#include "Cat.h"


Cat::Cat()
{
	cout << "Cat::Cat()" << endl;
}


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


void Cat::voice()
{
	cout << " miao miao miao miao " << endl;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值