zoukankan      html  css  js  c++  java
  • 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的析构函数,然后自动调用基类的析构函数。因此,使用虚析构函数可以确保正确的析构函数序列被调用!

  • 相关阅读:
    近期目标
    HDU
    BZOJ
    UVALive
    UVA
    HNOI2004 宠物收养所 (平衡二叉树)
    UVA
    HDU
    POJ
    康托展开与逆康托展开模板(O(n^2)/O(nlogn))
  • 原文地址:https://www.cnblogs.com/moonlightpoet/p/5664452.html
Copyright © 2011-2022 走看看