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 } ;
时间: 2024-10-24 18:23:17

c++之虚函数和基类指针的相关文章

OOP2(虚函数/抽象基类/访问控制与继承)

通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当某个虚函数通过指针或引用调用时,编译器产生的代码直到运行时才能确定应该调用哪个版本的函数.被调用的函数是与之绑定到指针或引用上的对象的动态类型相匹配的那一个 注意:动态绑定只有当我们通过指针或引用调用虚函数时才会发生.当我们通过一个具有普通类型(非引用非指针)的表达式调用虚函数时,在编译时就会将调用

构造函数为什么不能为虚函数 &amp;amp; 基类的析构函数为什么要为虚函数

一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数是虚的,就须要通过 vtable来调用,但是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到相应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚

C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构

一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型,我们如果想通过一个父类指针调用父类.子类中的同名函数的话,这个函数是有要求的: 在父类中,eat函数声明之前必须要加virtual声明eat()函数为虚函数. 一旦某个函数被声明为虚函数,那么所有派生类(子类)中eat()函数都是虚函数. 为了避免你在子类中写错虚函数,在C++11中,你可以在函数

c++虚函数实现与this指针

我们知道当我们sizeof 一个类的时候,类的成员函数是不计算在对象的大小的里的,这是为什么呢?因为类的成员函数不是属于某一个对象的,而是类的所有对象所共享的,就像static变量那样.如果虚函数和普通成员函数一样,那么我们就不能通过指向子类的基类指针来引用子类的方法了,因为我们将不知道调用哪个方法,多态就无从谈起.那么多态是怎么实现的呢? 虚函数.虚指针与虚表 我们可以做一个小实验 class A{ public: int a; virtual void myfun(){} }; class

基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------&gt; 可以返回派生类对象的引用或指针

您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. 百度和网页 http://bbs.csdn.net/topics/380238133 的作者无关,不对其内容负责.百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面. 首页 精选版块 移动开发 iOS Android Qt WP 云计算 IaaS Pass/SaaS 分布式计算/Hadoop J

派生表中第一个基类没有虚函数,派生类存在虚函数时的内存布局

单继承的例子: #include <iostream> using namespace std; class A { public: A() { a = 1; ch = 'a'; //ASCII码97 } private: int a; char ch; }; class C : public A { public: C() { c = 3; } virtual void print() { cout << "C" << endl; } privat

当this指针成为指向之类的基类指针时,也能形成多态

this指针: 1)对象中没有函数,只有成员变量 2)对象调用函数,通过this指针告诉函数是哪个对象自己谁. 1 #include<iostream> 2 using namespace std; 3 class Shape 4 { 5 public: 6 //void cal_display(Shape* this) 7 void cal_display(){ 8 display(); 9 this->display(); 10 } 11 private: 12 virtual vo

派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good

大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree是最底层基类(非虚类), CSamplerTree(虚类)派生自CTree,CMSamplerTree,CASamplerTree派生自CSamplerTree,                                                         CTree中包括两个成员

C++ 基类指针,子类指针,多态

基类指针和子类指针之间相互赋值(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,C++编译器将自动进行类型转换.因为子类对象也是一个基类对象. (2)将基类指针赋值给子类指针时,需要进行强制类型转换,C++编译器将不自动进行类型转换.因为基类对象不是一个子类对象.子类对象的自增部分是基类不具有的.(强制转换告诉编译器为对象增加子类所特有的部分) fish* fh1;  animal* an1 = new animal; fh1 = (fish*)an1; 原理: 当我们构造fish类的对