您的位置:首页 > 编程语言 > C语言/C++

c++面向接口编程,虚函数,虚析构函数

2010-12-25 11:48 288 查看
基类:

People.h

#pragma once

class People
{
public:
People(void);
virtual ~People(void);

virtual void show();
};


 

People.cpp

#include "People.h"
#include <iostream>
using namespace std;

People::People(void)
{
cout<<"People"<<endl;
}

People::~People(void)
{
cout<<"~People"<<endl;
}

void People::show()
{
cout<<"People show"<<endl;
}


 

 

派生类:

 

Student.h

 

#pragma once
#include "People.h"

class Student :public People
{
public:
Student(void);
~Student(void);
void show();
};


 

Student.cpp

 

#include "Student.h"
#include <iostream>
using namespace std;

Student::Student(void)
{
cout<<"student"<<endl;
}

Student::~Student(void)
{
cout<<"~student"<<endl;
}
void Student::show()
{
cout<<"student show"<<endl;
}


 

Teacher.h

 

#pragma once
#include "People.h"

class Teacher:public People
{
public:
Teacher(void);
~Teacher(void);

void show();
};


 

Teacher.cpp

 

#include "Teacher.h"
#include <iostream>
using namespace std;

Teacher::Teacher(void)
{
cout<<"Teacher"<<endl;
}

Teacher::~Teacher(void)
{
cout<<"~Teacher"<<endl;
}

void Teacher::show()
{
cout<<"teacher show"<<endl;
}


 

main.cpp

 

#include "Student.h"
#include "Teacher.h"

void main()
{
People *pObj = new Student();//面向接口编程,修改此句便可以达到更换模块的目的
//People *pObj = new Teacher();

pObj->show();

delete pObj;
}


 

 

 虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。
  如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。
  所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
  抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
  这里是一个例子:
  class awov { // awov = "abstract w/o
  // virtuals"
  public:
  virtual ~awov() = 0; // 声明一个纯虚析构函数
  };
  这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:
  awov::~awov() {} // 纯虚析构函数的定义
  这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这就是说,即使是抽象类,编译器也要产生对~awov的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,最后还是得回去把它添上。
  注意:如果声明虚析构函数为inline,将会避免调用它们时产生的开销,但编译器还是必然会在什么地方产生一个此函数的拷贝。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息