C++ 在继承中使用virtual

使用virtual:如果方法是通过引用类型或指针而不是对象调用的,它将确定使用哪一种方法。如果没有使用关键字irtual,程序将根据引用类型或指针类型选择方法;如果使用了irtual,程序将根据引用或指针指向的对象的类型来选择方法。对于一个函数ViewAcct()来说,如果ViewAcct()不是虚的,则程序的行为如下:
// behavior with non-virtual ViewAcct()
// method chosen according to reference type
Brass dom("Dominic Banker", 11224, 4183.45);
BrassPlus dot("Dorothy Banker", 12118, 2592.00);
Brass & b1_ref = dom;
Brass & b2_ref = dot;
b1_ref.ViewAcct();    // use Brass::ViewAcct()
b2_ref.ViewAcct();    // use Brass::ViewAcct()
引用变量的类型为Brass,所以选择了Brass::ViewAccount()。
使用Brass指针代替引用时,行为将与此类似。
如果ViewAcct()是虚的,则行为如下:
// behavior with virtual ViewAcct()
// method chosen according to object
Brass dom("Dominic Banker", 11224, 4183.45);
BrassPlus dot("Dorothy Banker", 12118, 2592.00);
Brass & b1_ref = dom;
Brass & b2_ref = dot;
b1_ref.ViewAcct();    // use Brass::ViewAcct()
b2_ref.ViewAcct();    // use BrassPlus::ViewAcct()
这里两个引用的类型都是Brass,但b2_ref引用的是一个BrassPlus对象,所以使用的是BrassPlus::ViewAcct()。使用Brass指针代替引用时,行为将类似。

虚析构函数:基类声明了一个虚析构函数。这样做是为了确保释放派生对象时,按正确的顺序调用析构函数。

3.演示虚方法的行为
假设要同时管理Brass和BrassPlus账户,如果能使用同一个数组来保存Brass和BrassPlus对象,将很有帮助,但这时不可能的。数组中所有元素的类型必须相同,而Brass和BrassPlus是不同的类型。然而,可以创建指向Brass的指针数组。这样,每个元素的类型都相同,但由于使用的是公有继承模型,因此Brass指针既可以指向Brass对象,也可以指向BrassPlus对象。因此,可以使用一个数组来表示多种类型的对象。这就是多态性。

4.为何需要虚析构函数
在程序清单13.10中,使用delete释放由new分配的对象的代码说明了为何基类应包含一个虚析构函数,虽然有时好像并不需要析构函数。如果析构函数不是虚的,则将纸雕用对应与指针类型的析构函数。对于程序清单13.10,这意味着只有Brass的析构函数被调用,即使指针指向的是一个BrassPlus对象。如果析构函数是虚的,将调用相应对象类型的析构函数。因此,如果指针指向的是BrassPlus对象,将调用BrassPlus的析构函数,然后自动调用基类的析构函数。因此,使用虚析构函数可以确保正确的析构函数序列被调用!

时间: 2024-11-08 14:47:00

C++ 在继承中使用virtual的相关文章

单继承与多继承中的虚函数表和虚函数指针

首先,我们了解一下何为单继承,何为多继承?? 单继承:一个子类只有一个直接父类. 多继承:一个子类有两个或多个直接父类. 单继承中的虚函数表分析: 示例程序: #include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virt

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

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

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

[转载]多重继承及虚继承中对象内存的分布

粘过来的效果还不错:) 本位通过不断地完善讲解多重继承及虚继承中对象内存的分布. 读的时候不要着急,第一遍会有些晕,第二遍就会好很多. 能帮助加深对多重继承及虚继承对象内存的分布情况. 多重继承及虚继承中对象内存的分布     这篇文章主要讲解G++编译器中虚继承的对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别.虚函数表的格式等一些大部分C++程序员都似是而非的概念. 本文是介绍C++的技术文章,假定读者对于C++有比较深入的认识,同时也需要一些汇编知识.

派生类的构造函数和析构函数和多继承中的二义性与虚函数

析构函数主要作用是对数据成员初始化. 1派生类的构造函数 派生类的构造函数定义的一般形式为: 派生类名::派生类名(基类所需形参,本类成员所需形参):基类1(基类1 参数表),基类2(基类2 参数表),···,基类n(基类n 参数表),对象成员1(对象1 参数表),对象成员2(对象2 参数表),···,对象成员m(对象m 参数表){ //本类基本类型数据成员初始化 } 如果使用基类无参构造函数,派生类构造函数形参表中不包含供给基类构造函数的参数.此时,系统会调用基类的默认构造函数.如果使用对象数

&lt;转&gt;C++继承中虚函数的使用

转自:http://blog.csdn.net/itolfn/article/details/7412364 一:继承中的指针问题. 1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对象时,这种指针只能访问派生对象从基类继承 而来的那些成员,不能访问子类特有的元素 ,除非应用强类型转换,例如有基类B和从B派生的子类D,则B *p;D  dd; p=&dd;是可以的,指针p只能访问从基类派生而来的成员,不能访问派生类D特有的成员.因为基类不 知道派生类中的这些成员. 2. 不能使派生类

C++继承中析构函数 构造函数的调用顺序以及虚析构函数

首先说说构造函数.大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数,仅仅有这样子类才干在构造函数里使用基类的成员,所以是创建子类时先调用基类的构造函数然后再调用自己的构造函数.通俗点说,你要用某些物品.但这些物品你没办法自己生产,自然就要等别人生产出来,你才干拿来用. 接着就是析构函数了,上面说到子类是将基类的成员变成自己的成员,那么基类就会仅仅存在子类中直到子类调

C++多重继承,菱形继承中构造函数的调用顺序

C++中多重继承不免会出现钻石继承,也就是继承类的两个基类同时又是同一个基类的继承类,当创建一个对象的时候,他们是按照什么样的顺序调用构造函数的呢. 如果不进行虚拟继承: class Base { public: Base() { cout<<"Base默认构造函数调用"<<endl; } Base(int i) { cout<<"Base参数构造函数调用"<<endl; cout<<i<<en

【转】c++继承中的内存布局

今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C++程序员,想要进一步提升技术水平的话,应该多了解一些语言的语意细节.对于使用VC++的程序员来说,还应该了解一些VC++对于C++的诠释. Inside the C++ Object Model虽然是一本好书,然而,书的篇幅多一些,又和具体的VC++关系小一些.因此,从篇幅和内容来看,译者认为本文