c++中的虚函数

多态是指使用相同的函数名来访问函数不同的实现方法,即“一种接口,多种方法”,用相同的形式访问一组通用的运算,每个运算可能对应的行为不同。

C++支持编译时多态和运行时多态,运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态。

1、运行时多态:

class A

{

public:

virtual  void play()

{

cout<< "A:play"<<endl;

}

};

class B : public class A

{

public:

void play()

{

cout<<"B: play"<<endl;

      }

};

int main()

{

A class_A;

B class_B;

A* p;

p = &class_A;

p -> play();

p = &class_B;

p -> play();

return 0;

}

自行查看运行结果 分析;

2、纯虚函数

纯虚函数的定义形式为 virtual void play() = 0;含有纯虚函数的类是不能实例化的,纯虚函数相当于接口,需要在派生类中实现函数;含有纯虚函数的类被叫做抽象类;在项目中纯虚函数的实践:

class Base_Test

{

void play()
     {

cout<<"Base_Test:play"<<endl;

     }

};

class Base

  {

   virtual void play() = 0;

virtual Base_Test test() = 0;

  };

3、虚基类

虚基类的引出主要是为了解决继承中的二义性问题,在多个派生类中,定义了同名函数,这时再在main函数里面通过基类调用该方法时,编译器就犯难了。因为它不知道你到底是想用哪一个派生类里面的方法。通过下面的例子来详细阐述:

大家都知道C++是支持多重继承的,那么就会遇到这样一个问题。如果一个派生类的多个基类是从一个共同的基类派生出来的,那么这个派生类会出现多个最底层基类的拷贝,程序中如何分辨呢。虚基类是让基类只有一个拷贝,程序中就不会出现不确定性。虚基类在派生类中声明:格式如下:class 派生类名:virtual 继承方式 基类。

#include <iostream>

using namespace std;

class Base
{
public :
Base()
{
cout<<"Base()"<<endl;
}

~Base()
{
cout<<"~Base()"<<endl;
}

};

class Continuator1 : public Base
{
public:
Continuator1()
{
cout<<"Continuator1()"<<endl;
}
~Continuator1()
{
cout<<"~Continuator1()"<<endl;
}
};

class Continuator2 : public Base
{
public:
Continuator2()
{
cout<<"Continuator2"<<endl;
}
~Continuator2()
{
cout<<"~Continuator2()"<<endl;
}
};

class Continuator : public Continuator1,public Continuator2
{
public:
Continuator()
{
cout<<"Continuator()"<<endl;
}

~Continuator()
{
cout<<"~Continuator()"<<endl;
}
private:
Base base;
};

int main()
{
Continuator c;

return 0;
}

这个例子的运行结果是:

从构造函数调用的顺序可以看出,在声明Continuator 对象时。首先调用基类Continuator1的构造,调用Continuator1的构造时就要先调用Base的构造函数,然后再调用Continuator1的构造函数,然后调用Continuator2,再调用成员对象的构造函数初始化成员对象base;最后调用派生类Continuator1的构造函数。析构函数调用顺序和构造函数调用顺序相反。

把Continuator1和Continuator2类的定义修改为:

class Continuator1 :virtual public Base
{
public:
Continuator1()
{
cout<<"Continuator1()"<<endl;
}
~Continuator1()
{
cout<<"~Continuator1()"<<endl;
}
};

class Continuator2 :virtual public Base
{
public:
Continuator2()
{
cout<<"Continuator2"<<endl;
}
~Continuator2()
{
cout<<"~Continuator2()"<<endl;
}
};

输出为:

由此可以看出虚基类的用法;

时间: 2024-10-18 22:21:52

c++中的虚函数的相关文章

第八章:不要在构造和析构函数中使用虚函数

前言 本文将讲解一个新手C++程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实现卖的类为其子类. 这三个类的对象初始化过程中,都需要完成注册的这么一件事情 (函数).然而,各自注册的具体行为是不同的. 有些人会写出以下这样的代码: 1 class Transaction { 2 public: 3 Transaction(); // 父类构造函数 4 //...... 5 pri

[C++]在构造函数及析构函数中调用虚函数

(ISO/IEC 14882:2011 section 12.7.4): Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).When a virtual function is called directly or indirectly from a constructor or from a destructor, inc

【C++】C++中的虚函数与纯虚函数

C++中的虚函数 先来看一下实际的场景,就很容易明白为什么要引入虚函数的概念.假设我们有一个基类Base,Base中有一个方法eat:有一个派生类Derived从基类继承来,并且覆盖(Override)了基类的eat:继承表明ISA(“是一个”)的关系,现在我们有一个基类的指针(引用)绑定到派生类对象(因为派生类对象是基类的一个特例,我们当然可以用基类指针指向派生类对象),当我们调用pBase->eat()的时候,我们希望调用的是Derived类的eat,而实际上调用的是Base类的eat,测试

C++中的虚函数解析[The explanation for virtual function of CPlusPlus]

1.什么是虚函数?                                                                                                                                               答:在C++的类中,使用virtual修饰的函数. 例如: virtual void speak() const { std::cout << "Mammal speak!\n&quo

谈谈c++中继承中的虚函数

c++继 承中的虚函数 c++是一种面向对象的编程语言的一个很明显的体现就是对继承机制的支持,c++中继承分很多种,按不同的分类有不同分类方法,比如可以按照基类的个数分为多继承和单继承,可以按照访问权限分为public继承.protected继承和private继承,按照是否是虚拟继承可以分为virtual继承和non-virtual继承.当然这里的分类标准都是有重叠的部分,比如,non-virtual继承又可以分为单继承和多继承.这里要讨论的是虚函数,因此主要从virtual和non-virt

EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #include <iostream> using namespace std; class cls1{ public: cls1(){ newMake(); }; ~cls1(){ deleteIt(); }; virtual void newMake(){ cout<<"cls1 make"<<endl; } virtual void deleteIt()

不要在构造和析构函数中使用虚函数

前言 本文将讲解一个新手 C++ 程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实现卖的类为其子类. 这三个类的对象初始化过程中,都需要完成注册的这么一件事情 (函数).然而,各自注册的具体行为是不同的. 有些人会写出以下这样的代码: 1 class Transaction { 2 public: 3 Transaction(); // 父类构造函数 4 //...... 5 p

构造函数和析构函数中的虚函数

构造派生类对象时首先运行基类构造函数初始化对象的基类部分.在执行基类构造函数时,对象的派生类部分是未初始化的.实际上,此时对象还不是一个派生类对象. 撤销派生类对象时,首先撤销它的派生类部分,然后按照与构造顺序的逆序撤销它的基类部分. 在这两种情况下,运行构造函数或析构函数的时候,对象都是不完整的.为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化.在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待. 构造或析构期间的对象类型对虚函数的绑定有影响. 如果在构造函数或析

C++构造函数中调用虚函数

谈谈关于构造函数中调用虚函数的情况,仅讨论单继承,不考虑虚拟继承和多重继承. 测试平台:VS2013 + Win7X64 一个例子: #include <stdlib.h> #include <stdio.h> class Base { private: int __data; public: Base() { this->Func(); } public: virtual void Func() { printf("Base::Func"); } };