zoukankan      html  css  js  c++  java
  • 关于如何在派生类的虚函数中调用被覆盖掉的同名基类的虚函数

    很久没写BLOG了,这是在设计实现中遇到的一个实际问题,就是类似下面的Java代码在C++中如何实现的问题

     1 import java.io.*;
     2 import java.util.*;
     3 
     4 class B
     5 {
     6     public void Print()
     7     {
     8         System.out.println("B");
     9     }
    10 }
    11 
    12 class D extends B
    13 {
    14     public void Print()
    15     {
    16         super.Print();
    17         System.out.println("D");
    18     }
    19 }
    20 
    21 class Main
    22 {
    23     public static void main(String[] args)
    24     {
    25         B obj= new D();
    26         obj.Print();
    27     }
    28 }
    29 

    有时候我们需要将所有子类方法中都会执行的代码放到基类方法中,或者可能这些代码是操作基类成员的本来就不应该放在子类,在Java中可以通过super来调用被覆盖掉的父类中的方法。

    我居然以为C++无法实现这一点,实在是太无知了。Google之后才知道原来可以这样用

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class B
     5 {
     6 public:
     7     virtual void Print()
     8     {
     9         puts("B");
    10     }
    11 };
    12 
    13 class D:public B
    14 {
    15 public:
    16     virtual void Print()
    17     {
    18         B::Print();
    19         puts("D");
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     B* p=new D();
    26     p->Print();
    27 }
    28 

    让我认为C++无法实现这点是有理由的,我们把virtual去掉看以下的代码
     1 #include <iostream>
     2 using namespace std;
     3 
     4 class B
     5 {
     6 public:
     7     void Print()
     8     {
     9         puts("B");
    10     }
    11 };
    12 
    13 class D:public B
    14 {
    15 public:
    16     void Print()
    17     {
    18         ((B*)(this))->Print();
    19         puts("D");
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     D* p=new D();
    26     p->Print();
    27 }
    28 

    这段代码是可以正确实行的,因为没有virtual,D类中的Print并没有覆盖B类中的Print,只是同名而已(这是很不好的做法,容易产生误解),所以这时不存在运行时绑定,我只好D* p=new D(); 我认为子类对象在内存中是这样的



    但是virtual的方法会被覆盖掉,也就是说对于D类的对象,已经没有B类的Print方法了。所以如果加上virtual我们就无法正确执行上面的代码了。

    可是B::Print(); 又是如何实现的呢?
  • 相关阅读:
    SSM添加数据后自动获取ID
    EasyUI分页
    JavaScript增强AJAX基础
    高德地图MapAPI地图展示
    项目json代码
    JavaScript 事件机制
    JavaScript event flow
    java和JavaScript的区别
    history of program
    javaScript obj
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/1994859.html
Copyright © 2011-2022 走看看