• c++之虚函数和基类指针


      1. 基类指针虽然获取派生类对象地址,却只能访问派生类从基类继承的成员
     1 #include <iostream>
     2 using namespace std;
     3 
     4 //通过基类指针只能访问从基类继承的成员
     5 class A
     6 {
     7 public:
     8     A(char x)
     9     {
    10         this->x = x;
    11     }
    12     //void virtual who()    //基类定义虚函数,则派生类的重定义版本默认为虚函数
    13     void who()    //除非定义虚函数,否则基类指针无法访问派生类的非继承的成员
    14     {
    15         cout << "A class" << x << endl;
    16     }
    17 protected:
    18     char x;
    19 };
    20 
    21 class B:public A
    22 {
    23 public:
    24     B(char x,char y):A(x)
    25     {
    26         this->y = y;
    27     }
    28     void who()
    29     {
    30         cout<< "B class" << x << "," << y<< endl;
    31     }
    32 protected:
    33     char y;
    34 };
    35 class C:public B
    36 {
    37 public:
    38     C(char x,char y,char z):B(x,y)
    39     {
    40         this->z = z;
    41     }
    42     void who()
    43     {
    44         cout<< "C class " << x << "," << y << "," << z << endl;
    45     }
    46 protected:
    47     char z;
    48 };
    49 
    50 void main()
    51 {
    52     A a('A'); 
    53     B b('T','O');
    54     C c('E','N','D');
    55     //定义基类指针
    56     A* aa;
    57     aa = &a;
    58     aa->who();
    59     aa = &b;
    60     //只能调用从基类继承的函数
    61     aa->who();
    62     aa = & c;
    63     //只能调用从基类继承的函数
    64     aa->who();
    65     //通过对象调用自身的成员函数
    66     b.who();
    67     //基类指针做类型转换,调用转换后的类型的类成员函数
    68     ((C*)aa)->who();
    69 }

    2.虚函数和基类指针

    注意:

      一个虚函数,在派生类层界面相同的重载函数都保持虚特性
      虚函数必须是类的成员函数
      不能将友元说明为虚函数,但虚函数可以是另一个类的友元
      析构函数可以是虚函数,但构造函数不能是虚函数

    3.虚函数的重载特性

      在派生类中重载基类的虚函数要求函数名、返回类型、参数个数、

      参数类型和顺序完全相同

      如果仅仅返回类型不同,C++认为是错误重载
      如果函数原型不同,仅函数名相同,丢失虚特性 
     1 例:
     2 class  base
     3 { public : 
     4       virtual  void  vf1 ( ) ;
     5       virtual  void  vf2 ( ) ;
     6       virtual  void  vf3 ( ) ;
     7       void  f ( ) ;
     8  } ;
     9 class  derived : public  base
    10 { public : 
    11       void  vf1 ( ) ;        // 虚函数
    12       void  vf2 ( int ) ;    // 重载,参数不同,虚特性丢失
    13       char  vf3 ( ) ;        // error,仅返回类型不同
    14       void f ( ) ;        // 非虚函数重载
    15  } ;
    16 
    17 void  g ( ) 
    18 { derived   d ;
    19    base  * bp = & d ;        // 基类指针指向派生类对象
    20    bp -> vf1 ( ) ;            // 调用 deriver :: vf1 ( )
    21    bp -> vf2 ( ) ;            // 调用 base :: vf2 ( )
    22    bp -> f ( ) ;            // 调用 base :: f ( )
    23 } ;
  • 相关阅读:
    maven打包出错: Failed to clean project: Failed to delete
    Image.Save()发生“GDI+ 中发生一般性错误”
    Vue.js——60分钟快速入门
    PHP-输入变量
    ThinkPHP框架开发的应用的标准执行流程
    ThinkPHP 3.2.2 在 volist 多重循环嵌套中使用 if 判断标签
    ThinkPHP 数据库操作之数据表模型和基础模型 ( Model )
    Namespace declaration statement has to be the very first statement in the script
    ThinkPHP 学习笔记 ( 一 ) 项目部署:应用部署方式与模块分组部署方式
    ThinkPHP 3.2.3 简单后台模块开发(一)常用配置
  • 原文地址:https://www.cnblogs.com/Smart-Du/p/4336208.html
Copyright © 2020-2023  润新知