分配给继承类时为继承类型分配内存 [英] allocation of memory for inherited types when assigning to a inheriting class

查看:98
本文介绍了分配给继承类时为继承类型分配内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个简单的问题.假设我有两个类似下面的类.

Hi,

I have a simple question. Suppose I have two classes like below.

class Room
{}

class LivingRoom : Room
{
    int p1;
    public void Method()
    {
    }
}



并假设我在主程序中创建了LivingRoom类的新实例,并将其分配给Room.



And suppose I am creating a new instance of class LivingRoom in my main program and assigning it to Room.

static void Main(string[] args)
        {
            Room r1 = new LivingRoom();
            Console.ReadLine();
        }



创建LivingRoom实例时,内存中至少应有未分配的指向LivingRoom对象的属性p1和方法Method()的指针.但是Room类中没有相应的属性和方法.基类中没有这样的属性和方法,是否应该没有错误? Room类中没有指针,也没有属性来保存继承的类LivingRoom中存在的内容?

问候,



When a LivingRoom instance is created, there should be at least unassigned pointers to property p1 and method Method() of LivingRoom object in the memory. But there are no corresponding properties and methods in Room class. Should not there be an error as there are not such properties and method in the base class ? There is no pointer in Room class or a property to hold what exists in the inherited class LivingRoom ?

Regards,

推荐答案

将LivingRoom分配给"r1"时,您没有为其分配房间:您分配了一个继承的类,它不会被截断或以其他方式转换为房间. Room变量"r1"仍将作为Room起作用,您可以访问Room的所有属性和方法,但是在将变量转换回LivingRoom之前,您无法访问LivingRoom的属性或方法:

When you assign your LivingRoom to "r1", you do not assign a Room to it: you assign an inherited class, it is not truncated or otherwise converted to a Room. The Room variable "r1" will still work as a Room, you can access all of the properties and methods of a Room, but you cannot access the properties or methods of a LivingRoom until you have cast the variable back to a LivingRoom:

using System;

namespace ConsoleTester
    {
    public class Room
        {
        public int r;
        }

    public class LivingRoom : Room
        {
        public int p1;
        public void Method()
            {
            }
        }
    class Program
        {
        static void Main(string[] args)
            {
            Room r1 = new LivingRoom();
            r1.r = 14;    // Compiler is happy
            r1.p1 = 14;   // Compiler complains: "Room does not contain a definition of p1"
            ((LivingRoom) r1).p1 = 14; //Compiler is happy.
            Console.ReadLine();
            }
        }
    }




问题出在转换上.当r1转换为继承类型时,它必须持有对LivingRoom对象的Method()的引用.它只是隐藏的并不意味着不存在对该引用的引用.这个正确吗?"

不完全是:您在想错了.

"r1"始终保持对房间的引用.它不知道Room类之外的任何内容.它实际上拥有对LivingRoom实例的引用与它无关:它甚至不知道LivingRooms存在! LivingRoom实例具有成为LivingRoom所需的所有信息,以及成为Room的所有信息.




"The problem is in casting. When r1 is cast to inherited type, it must be holding a reference to the Method() of LivingRoom object. That it is just hidden does not mean that there exists no reference to it. Is this correct ?"

Not really: you are thinking about it wrong.

"r1" holds a reference to a Room all the time. It doesn''t know about anything outside the Room class. That it actually holds a reference to a LivingRoom instance is irrelevant to it: it doesn''t even know that LivingRooms exist! The LivingRoom instance has all the info it needs to be a LivingRoom, as well as all the info to be a Room.


您显然没有意识到面向对象的基础知识.

首先要了解:涉及两种不同的类型:编译时类型和运行时类型.

You apparently unaware of the very object-oriented fundamentals.

First to understand: there are two different types involved: compile-time and run-time type.

class MyBaseClass { internal byte somethingOld; }
class MyDerivedClass : MyBaseClass { internal int somethingNew; }

MyBaseClass b = //the variable is of complile-time class MyBaseClass
    new MyDerivedClass(); //
bool isDerived = b is MyDerivedClass; //returns true

//can be down-casted:
MyDerivedClass derived = b as MyDerivedClass; //could be null, but it is not
isDerived = derived != null; //still true
derived.somethingNew = 13; //will work



您的指针"术语对于.NET是不正确的,但是让我们对此稍作猜测:在某种程度上,您可以将.NET引用作为指针".该实例指向一个内存块.创建MyBaseClass的实例时,此块中只有somethingOld,而没有somethingNew.创建派生类时,内存块看起来完全一样,但是somethingNew附加到了它.变量指向统一的内存块.从变量b的角度来看,它指向较小的块,但同时它指向扩展的内存块;公用部分与MyBaseClass相同.

—SA



You "pointer" terminology is incorrect for .NET, but let''s forger about it for a while: you can thing of .NET references as of "pointers", to a certain point. The instance points to a block of memory. When you create an instance of MyBaseClass, you have only somethingOld in this block, not somethingNew. When you create derived class, the block of memory looks exactly the same, but somethingNew is appended to it. A variables point to united block of memory. From the standpoint of the variable b it points to smaller block, but at the same time it points to extended block of memory; common part is the same as that of MyBaseClass.

—SA


这篇关于分配给继承类时为继承类型分配内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆