“this.字段”如果出现在父类代码中,指的就是父类属性。
“this.方法”不管出现在父类还是子类代码中,指的都是子类方法。
“this.字段”如果出现在子类代码中,指的就是子类属性。

在程序的时候往往会看到在父类的一个函数中用到"this",我们知道this指向当前的这个对象,具体点就是当前运行中的对象,如果在父类中有虚函数,那么这个this调用的方法就可能是子类中的实现的虚函数。

其实这些在我们学习this和继承的时候老师都会提到,而且老师会讲到内存结构,比如一构造一个子类的时候,会先构造父类,然后将父类的这个内存块作为子类内存块的一部分,比如说class C继承了class B,而B又继承了class a,那么C的内存结构可以看下面的图:

也就是说子类的内存结构=父类的内存结构+子类特有的部分。如果使用了虚函数,我们知道虚函数在C++和C#中有很重要的角色,可以在运行时识别对象,有一个专业术语叫做RTTI.也因为这样,有了多态的说法,多态这个玩意在程序中很有用的,具体的我就不在这里空谈了。

上面说了,在子类对象创建的时候,先创建父类对象,那么如果在父类的构造函数中出现了this,那情况如何,如果在父类的其他函数中出现this,这个我们都能想到,通过this调用的方法要么是父类的方法,要么是子类的实现了父类虚方法的方法(或者重写),可能比较拗口。那么父类的构造函数中的this情况如何?在这里我分别在C#和C++中模拟,发现C#中的这个this,会直接调用子类的实现父类的虚方法(或者重写),而C++中则是调用父类的方法,当构造函数结束后,调用的则是子类,让我自己去考虑的话,我觉得C++的才是正确的,因为在构造子类的时候先调用父类的构造函数,而这个时候子类还没有产生,所以出现在父类的构造函数中的this调用的方法应该是父类的,但是C#为什么不一样呢?这我不清楚,只能猜测,因为构造子类,调用父类,其实父类这个时候是作为子类内存的部分的,如果这样的话,好像也没错?我只能将这个归结为编译器的差异。

这里我分别给出两种语言的代码,有兴趣的可以试试。

C#代码:

namespace ConsoleInherit
{
    class Program
    {
        static void Main(string[]
args)
        {
            int x
= CFish.s;
            CFish
pFish =
new CFish();
 
            CAnimal
pA = pFish;
 
            pA.eat();
 
            pA.yeep();
 
            Console.WriteLine();
        }
    }
}
 
 
namespace ConsoleInherit
{
    public class CAnimal
    {
        CAnimal
Ca;
 
       public  CAnimal()
        {
            Ca
=
this;
            Ca.yeep();//和C++
不一样,这个this直接调用子类的虚函数
            Ca.eat();
            this.eat();
            
        }
        public void eat()
       {
             Ca.yeep();
            Console.Write("Animal
eat!"
);
 
        }
 
        public virtual void yeep()
        {
            Console.Write("Animal
yepp!"
);
        }
    }
}
 
 
namespace ConsoleInherit
{
    class CFish:CAnimal
    {
        public new void eat()
        {
 
            Console.Write("fish
eat!"
);
 
        }
       public static int s;
        static void Get()
        {
            CFish
pFish =
new CFish();
        }
 
        public void swim()
        {
            Console.Write("fish
swim!"
);
 
        }
 
        public override void yeep()
        {
            Console.Write("Fish
yeep!"
);
        }
    }
}

 

C++的代码:

#pragma
once
class CAnimal
{
     
public:
    CAnimal
*Ca;
    CAnimal(void);
    ~CAnimal(void);
    void eat();
    void breathe();
    virtual void yeep();
 
};
 
 
 
 
using namespace std;
 
CAnimal::CAnimal(void)
{
    Ca=this;
    Ca->yeep();//为什么是父类的?,难道是因为子类还没有实例化完?和C#中不一样
     
}
 
 
CAnimal::~CAnimal(void)
{
}
void CAnimal::eat()
{  
Ca->yeep();
//这里调用的是子类的
    cout<<"Animal
eat"
<<endl;
}
void CAnimal::breathe()
{
    cout<<"Animal
breathe"
<<endl;
}
void CAnimal::yeep()
{
    cout<<"Animal
yeep"
<<endl;
}
 
 
 
#pragma
once
#include
"animal.h"
class CFish:public CAnimal
      {
          public:
              CFish();
              ~CFish();
              void swim();
              void breathe();
              virtual void yeep();
      };
 
 
 
 
 
using namespace std;
 
 
CFish::CFish(void)
{
    //调用Ca=this;
}
 
 
CFish::~CFish(void)
{
}
void CFish::
swim()
{
    cout<<"Fish
swim"
<<endl;
     
}
void CFish::breathe()
{
    cout<<"
Fish breathe"
<<endl;
 
}
void CFish::yeep()
{
    cout<<"
Fish yeep"
<<endl;
}
 
 
 
CFish
cFish;
 
    cFish.eat();//继承父类的方法
    cFish.swim();
    //cFish.breathe();
    CAnimal
*Canimal;
     
    CAnimal
pAx=(CAnimal)cFish;
 
    pAx.eat();
 
    Canimal=&cFish;
 
    //Canimal->breathe();//重载是由指针类型决定,虚函数是由具体的对象决定
 
    //Canimal->yep();
    Canimal->Ca->yeep();
    Canimal->Ca->breathe();//调用子类的虚函数
    cout<<""<<endl;

 

父类中“this” 指向问题的更多相关文章

  1. 关于java基础中,接口里面父类的对象指向子类的引用

    父类的引用指向子类的对象,它只能看的到父类的那些方法~ 子类自身的方法看不到-- ······························· 如: interface Singer { //定义了 ...

  2. OC 继承子类对象调用方法机制 子类对象访问父类中的实例变量

    在继承中,子类对象如何调用到正确方法的机制 每一个Objective - C对象都有一个隐藏的指针指向类的代码,当向一个对象发送消息的时候,当前的对象会首先在当前类里去查找相应的方法,如果找到的话,直 ...

  3. c++纯虚函数在父类中调用的规避

    构造和析构函数不允许调用纯虚函数,可以先调用虚函数,里面再调用纯虚函数实现. class Base{public:    virtual void foo()=0;    Base() { call_ ...

  4. 关于父类中的this指针的问题

    在处理一个消息推送的问题的时候遇到个小问题,比如A是B的子类,当A生成实例时,会执行父类的构造函数,那么在父类中,this会是什么类型呢? 于是做了个小测试 子类ChildClass: public ...

  5. Java子类对于父类中static方法的继承

    今天看到了Java中子类继承父类的一个相关讨论,在网上综合了各家的观点,写下了一篇简短的总结. 问题如下,在父类中含有staic修饰的静态方法,那么子类在继承父类以后可不可以重写父类中的静态方法呢? ...

  6. java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包

    Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...

  7. JavaScript中this指向的简单理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  8. 子类可以有跟父类中同名的方法,但是会重写父类中的方法,甚至是root class中的方法

    /* 子类可以重写父类中的方法,甚至是root class中的方法,比如NSObeject 的new方法,但是后提示警告如下 Method is expected to return an insta ...

  9. java中子类与父类中隐含的this引用的分析

    /* 看一下下面的程序,看是否你的答案和运行的答案是否一致! */ class Parent{ public int x; public Parent p; public Parent(){} pub ...

随机推荐

  1. 【Unity3D游戏开发】性能优化之spine提高80~90%的效率 (三一)

    Spine效率低 Unity项目加载spine动画,经常会出现卡顿的情况,如游戏中瞬间播放一个动画,打开一个带spine动画的界面.尤其是SkeletonRenderer.Awake时,会瞬间出现大量 ...

  2. linux下vim命令详解

    高级一些的编辑器,都会包含宏功能,vim当然不能缺少了,在vim中使用宏是非常方便的::qx     开始记录宏,并将结果存入寄存器xq     退出记录模式@x     播放记录在x寄存器中的宏命令 ...

  3. QT 加载c语言编译的动态库

    QLibrary lib("./libprint.so");//库的路径if(lib.load()){    typedef void(*AddFunction)(char *st ...

  4. [Effective Java]第十章 并发

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. 线程入门之join方法

    package com.thread; /** * <join:将某线程加入进来,相当于方法调用,也叫合并某个线程> * <功能详细描述> * * @author 95Yang ...

  6. JS——JavaScript Confirm

    function show_confirm(){var r=confirm("Press a button!");if (r==true) { alert("You pr ...

  7. 序列的方法(str,list,tuple)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在快速教程中,我们了解了最基本的序列(sequence).回忆一下,序列包含有定值 ...

  8. python_way day16 DOM

    Python_way day16 1.Dom  (找到html中的标签) 一.DOM 1.查找元素 直接查找 document.getElementById 根据ID获取一个标签 --->这里是 ...

  9. C# 线程(三):如何操纵一个线程

    From : http://kb.cnblogs.com/page/42529/ 下面我们就动手来创建一个线程,使用Thread类创建线程时,只需提供线程入口即可.(线程入口使程序知道该让这个线程干什 ...

  10. CentOS6.4_常用命令

    1. 查看本机是否安装了 xxx软件,以及 xxx软件 的版本信息等: rpm -qa |grep  xxx(xxx代表软件名) 2. rpm -ivh 要安装的rpm文件包 3. 不care依赖项的 ...