“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. 【转载】.NET程序员走向高端必读书单汇总

    原文:.NET程序员走向高端必读书单汇总 .NET程序员走向高端必读书单汇总 一.知识树 1. 基本能力 1.1 数学 1.2 英语 1.3 语言表达 2. 计算机组织与体系结构 3. 算法与数据结构 ...

  2. Python学习遇到的问题

    UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position

  3. 09.VMWare虚拟机copy后网卡不是eth0解决办法

    0.如果VM虚拟机已经复制了,网卡已经不是eth0了,看下面1--->步骤,如果还没复制将要复制,只看1就行     点击I copy it.这时虚拟机会在开机时检查是否次网卡无力地址已经存在, ...

  4. 现在有T1、T2、T3三个线程,怎样保证T2在T1执行完后执行,T3在T2执行完后执行?使用Join

    public class TestJoin { public static void main(String[] args) { Thread t1 = new Thread(new T1(), &q ...

  5. jQuery EasyUI DataGrid API 中文文档

        扩展自$.fn.panel.defaults,用 $.fn.datagrid.defaults重写了 defaults . 依赖 panel resizable linkbutton pagi ...

  6. JavaWEB 常用开发模式MVC+三层结构

    MVC开发模式: M:  Model   -- JavaBean C:  Controler   --  Servlet V: View   --- JSP 不会在word里面画画,所以就直接截了 老 ...

  7. XML约束——Schema约束

    XML Schema 也是一种用于定义和描述 XML 文档结构与内容的模式语言,其出现是为了克服 DTD 的局限性 XML Schema VS DTD: •XML Schema符合XML语法结构. • ...

  8. (七)C语言中的void 和void 指针类型

    许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...

  9. 5.6 a、b交换

    答案:int max = ((a+b)+abs(a-b))/2;

  10. Linux用户查询

    用户列表文件:/etc/passwd 用户组列表文件:/etc/group 查看系统中有哪些用户:cut -d : -f 1 /etc/passwd 查看可以登录系统的用户:cat /etc/pass ...