c++中基类与派生类中隐含的this指针的分析

先不要看结果,看一下你是否真正了解了this指针?

#include<iostream>
using namespace std;

class Parent{
     public:
         int x;
         Parent *p;
     public:
         Parent(){}
         Parent(int x){
           this->x=x;
           p=this;
        }
         virtual void f(){
            cout<<"Parent::f()"<<endl;
        }
        void g(){
            cout<<"Parent::g()"<<endl;
        }

        void h(){
            cout<<"Parent::h()"<<endl;
            f();
            g();
            y();
            cout<<"LOOK HERE: "<<x<<endl;
        }

        private:
            void y(){
                cout<<"Parent::y()"<<endl;
            }
};

class Child : public Parent{
    public:
        int x;

    public:
        Child(){}
        Child(int x) : Parent(x+5){//正确的调用父类构造函数要写在初始化型参列表中 

             //这样企图调用父类的构造函数是错误的,因为这是另外创造了一个临时对象,函数结束之后就什么都没有了!
            //Parent(x+5);
            this->x=x;
        }
        void f(){
            cout<<"Child f()"<<endl;
        }
        void g(){
            cout<<"Child g()"<<endl;
        }
};

int main(){
    //例一
    Child *ch=new Child();
    ch->h();
    cout<<endl;
    //例二:
    ch=new Child(5);
    ch->h();
    cout<<endl;

    //例三:
    ch->p->h();
    return 0;
}

/*
Parent::h()
Child f()
Parent::g()
Parent::y()
LOOK HERE: 9306304

Parent::h()
Child f()
Parent::g()
Parent::y()
LOOK HERE: 10

Parent::h()
Child f()
Parent::g()
Parent::y()
LOOK HERE: 10
*/

首先Child继承了Parent中的 h()方法!
我们new 了一个Child类的对象XXX, 用ch指向了它!
当ch去调用h()方法的时候,好了关键的问题来了,那就是此时的this指针到底是指向谁的....

要知道,this指针是和对象相关的,所以无论怎样,那么调用h()方法的是XXX这个对象,
那么this就是指向XXX这个对象XXX!在入栈的时候,this也一同被压入!既然this是指向XXX
的,为什么会调用基类的g()方法呢?然后又调用的是派生类中的f()方法呢?(注意:g()方法
和f()方法在基类和派生类中都有).....

仔细看一下,是不是感觉和派生类向上转型为基类的多态差不多啊。子类在调用h()方法时,其实
默认将this的类型进行了向上提升,也就是由Child* this -> Parent* this;想一想这是必须的,
why?因为h()只是派生类继承基类的,并没有进行重写!如果没有进行this的类型提升,那么
如果h()方法中存在对基类私有成员的访问,比如这个子类中的y()方法是私有的!h()中调用了
y(); 也就是this->y();是不是矛盾了?派生类中怎么可以访问基类中的私有成员呢???

所以this的类型一定向上提升了!
如果还是不信,那你看一下 样例2 中的x值是不是输出的是基类中的 x 的值!
再看一看 样例3中的输出是不是和样例2的输出时一样的!从f()的调用和g()调用
可以看出是多态的结果...

时间: 2024-11-18 03:07:06

c++中基类与派生类中隐含的this指针的分析的相关文章

msdn-派生类存放在基类类型vector中,怎么用派生类的函数?

问题描述 派生类存放在基类类型vector中,怎么用派生类的函数? 我已经成功将派生类存放在基类类型的vector表中,也能定位位置,就是不知道怎么使用派生类的函数,只能用基类的函数,求解啊! #include#include#include#includeusing namespace std;class people{public: people() { name = new char[20]; code = 0; sex = new char[8]; number = new char[2

详解C++中基类与派生类的转换以及虚基类_C 语言

C++基类与派生类的转换 在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中全部都按原样保留下来了,在派生类外可以调用基类的公用成员函数访问基类的私有成员.因此,公用派生类具有基类的全部功能,所有基类能够实现的功能, 公用派生类都能实现.而非公用派生类(私有或保护派生类)不能实现基类的全部功能(例如在派生类外不能调用基类的公用成员函数访问基类的私有成员).因此,只有公用派生类才是基类真正的

详谈C++中虚基类在派生类中的内存布局_C 语言

今天重温C++的知识,当看到虚基类这点的时候,那时候也没有太过追究,就是知道虚基类是消除了类继承之间的二义性问题而已,可是很是好奇,它是怎么消除的,内存布局是怎么分配的呢?于是就深入研究了一下,具体的原理如下所示: 在C++中,obj是一个类的对象,p是指向obj的指针,该类里面有个数据成员mem,请问obj.mem和p->mem在实现和效率上有什么不同. 答案是:只有一种情况下才有重大差异,该情况必须满足以下3个条件: (1).obj 是一个虚拟继承的派生类的对象 (2).mem是从虚拟基类派

C++中基类和派生类之间的转换实例教程_C 语言

本文实例讲解了C++中基类和派生类之间的转换.对于深入理解C++面向对象程序设计有一定的帮助作用.此处需要注意:本文实例讲解内容的前提是派生类继承基类的方式是公有继承,关键字public.具体分析如下: 以下程序为讲解示例: #include<iostream> using namespace std; class A { public: A(int m1, int n1):m(m1), n(n1){} void display(); private: int m; int n; }; voi

对象-C++多态基类和派生类之间转换

问题描述 C++多态基类和派生类之间转换 #include <iostream> #include<iostream> using namespace std; class A { public: void foo() { printf("1 "); } virtual void fun() { printf("2 "); } }; class B : public A { public: void foo() { printf("

消息印射-两个MFC类实现多重继承,虚继承基类时候派生类的消息映射出错,求解决方法

问题描述 两个MFC类实现多重继承,虚继承基类时候派生类的消息映射出错,求解决方法 一个类实现了可悬浮侧靠的对话框,另一个类实现了有滑动条的对话框,然后我就想到了多重继承来实现一个可悬靠带滑动条的对话框.由于看书上说要虚继承基类,并且在初始化成员类表中显示初始化基类,这些都有做,但是在消息印射部分出了问题. 这里编辑代码不方便,详细情况在帖子中 http://bbs.csdn.net/topics/390871222 不胜感激

定义基类和派生类

定义基类 对于基类,我们需要记住的是作为继承关系中根节点的类通常都会定义一个虚析构函数. 基类通常都会定义一个虚析构函数,即使该函数不执行任何实际操作也是如此.   成员函数和继承 派生类可以继承其基类的成员,也可以对基类中的虚函数进行重新定义.换句话说,派生类需要对这些操作提供自己的新定义以覆盖(override)从基类继承而来的旧定义. 在C++语言中,基类必须将它的两种成员函数区分开来:一种是基类希望其派生类进行覆盖的函数:另一种是基类希望派生类直接继承而不要改变的函数.对于前者,基类通过

【C/C++学院】0825-类模板/final_override/类模板与普通类的派生类模板虚函数抽象模板类/类模板友元/位运算算法以及类声明/Rtti 实时类型检测/高级new创建/类以及函数包装器

类模板 类模板多个类型默认类型简单数组模板 #pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #include "myArray.h" template <class T=int>//每一个函数都需要加上一个默认的值 myArray<T>::myArray() //类模板成员函数在外部,需要加载类型初始

MFC中CWnd类及其派生类对话框、消息处理、窗口操作

http://hi.baidu.com/xiaorida21/blog/item/8d8eb77a22eedee52e73b39e.html CWnd类 我们在屏幕上看到的所有对象都和窗口有关,它们或者派生于CWnd,属继承关系,如对话框.工具栏.状态栏.子控件:或者被CWnd合成,属服务员与服务对象关系,如图标.菜单.显示设备. CWnd类封装的窗口操作主要包含窗口的创建和销毁.操作窗口风格.操作窗口状态.窗口子类化.获取指定窗口等. 当然,CWnd还实现了其他功能: 1.绘制窗口 GetDC