食类 [英] Cannibal Classes

查看:150
本文介绍了食类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在了一段时间,我一直在试图环绕为什么一些吃人类可以编译原因,我的头。

在我继续下去,也许我应该解释一下我所说的吃人的类。不知道如果我只是发明了这个词,或者如果它已经存在了一段时间,甚至如果我正确地使用它,但是这并不重要,现在。

我基本上调用一个食人族类,消费本身就是一个类。换句话说类的接口声明了自己的类型的成员。例如:

 类Foo
{
    公共富SomeFoo;
}
 

正如你可以在上面看到,类Foo有一个类型的成员美孚(本身)。

现在,我第一次看到这个(looong时间前)我没有的东西它要编译,但它让我吃惊它编译。为什么我没有事情的原因,这将汇编是因为我这个尖叫某些类型的递归恶梦。

要稍微更复杂的是,我决定尝试同样的事情,但使类结构,例如:

 结构美孚
{
    公共富SomeFoo;
}
 

不幸的是,这并不能编译,而不是你的错误: 结构成员类型'富'的'Foo.SomeFoo引起的结构布局

在我看来,一个编译错误,使更多的意义上,没有错误,但我相信有大部分是一个合乎逻辑的解释这种行为,所以我在想,如果你们的任何人都可以解释这种现象。

感谢。

解决方案

您不能设计一个结构类似,这是因为结构时,会分配一些默认值进行初始化的原因。所以,当你有一个struct 像你描述的,你创建一个 ...

 富X; // X =默认(美孚)
 

它调用的默认构造函数。然而,默认的构造函数已经给了 Foo.SomeFoo 字段的默认值。

嗯,怎么就找不到呢?它叫默认(美孚)。其中,以构建一个,已经给了 Foo.SomeFoo 字段的默认值...正如你猜测,这是一个递归的噩梦。

既然你可以创建一个空引用类,并从实际创建紧跟在类的一个实例不要,没有任何问题;你可以叫新富() Foo.SomeFoo 将只是空。没有递归必要的。

补遗:当你考虑这个,如果你还是有疑惑,我想其他的答案有考虑到它(相同的基本问题,不同的方法),另一种好办法 - 当程序分配内存为,怎么它应该做的呢?什么是的sizeof(美孚)包含了一些东西,然后又是整个?你不能做到这一点。

相反,如果它是一个类,那就只需要分配几个字节的引用,而不是实际的,而且也没有问题。

For sometime now, I have been trying to wrap my head around the reason why some "cannibal" classes are allowed to compile.

Before I continue, perhaps I should explain what I call a "cannibal" class. Not sure if I just invented that term or if it has been around for a while or even if I am using it correctly but that is not important right now.

I basically call a cannibal class a class that consumes itself. In other words a class whose interface declares members of its own type. For example:

class Foo
{
    public Foo SomeFoo; 
}

As you can see above, class Foo has a member of type Foo (itself).

Now, the first time I saw this (looong time ago) I didn’t thing it was going to compile but it to my surprise it does compile. The reason why I didn’t thing this would compile is because to me this screams some type of recursive nightmare.

To complicate things a little further, I decided to try the same thing but making the class a struct such as:

struct Foo
{
    public Foo SomeFoo; 
}

Unfortunately, this does not compile, instead you get error: Struct member 'Foo.SomeFoo' of type 'Foo' causes a cycle in the struct layout

To me, a compile error makes more sense that no error but I am sure there most be a logical explanation to this behavior so I was wondering if anyone of you guys could explain this behavior.

Thanks.

解决方案

The reason you can't design a struct like this is because structs have to be initialized when they are allocated with some default values. So, when you have a struct Foo like you described and you create a Foo...

Foo x; // x = default(Foo)

it calls the default constructor for Foo. However, that default constructor has to give a default value for the Foo.SomeFoo field.

Well, how's it find that? It has to call default(Foo). Which, in order to construct a Foo, has to give a default value for the Foo.SomeFoo field... As you surmised, this is a recursive nightmare.

Since you can create a null reference to a class, and refrain from actually creating an instance of the class immediately, there's no problem; you can call new Foo() and Foo.SomeFoo will just be null. No recursion necessary.

ADDENDUM: When you're thinking about this, if you're still confused, I think the other answers have another good way of considering it (same essential problem, different approach) -- when the program allocates memory for a Foo, how's it supposed to do it? What's sizeof(Foo) when Foo contains some stuff, and then another whole Foo? You can't do that.

Instead, if it were a class, it would just have to allocate a couple bytes for a reference to a Foo, not an actual Foo, and there's no problem.

这篇关于食类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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