import std.stdio;
class IntegerContainer
{
public int Integer = 1;
}
void DoubleInteger(IntegerContainer Container)
{
Container.Integer *= 2;
}
void main()
{
IntegerContainer Container = new IntegerContainer; // Internal integer defaults to one.
DoubleInteger(Container); // Internal integer changes to two inside the function.
writefln(Container.Integer); // Prints "2."
}
在D中,引用与值是类型的特征,而不是函数参数。来自C ++,这对我来说真的很糟糕。
看起来有一个ref
关键字来强制接受struct
的函数的传递引用。是否有通过值传递class
es的等价物?
例如,假设我想创建一个函数函数,它返回自定义容器类的排序副本。在C ++中,这与使用Foo Sorted(Foo Object)
一样简单,而不是Foo Sort(Foo& Object)
。在没有手动复制对象的情况下,我认为无法在D中执行此操作。
答案 0 :(得分:11)
类是设计的引用类型。它们不应该被价值所传递。它与Java和C#完全相同。但是,与Java和C#不同,D也有完整的用户定义值类型,因为它具有结构(C#也具有结构,但它们很多更受限制)。 C ++将两者混为一谈的事实导致object slicing等问题。
现在,当您想要复制引用类型时,显然是次。解决方法是cloning。你给你的类一个clone
函数,它返回它被调用的对象的副本。这样,您可以在需要时复制它,并且只在需要时才复制它。 Java和C#具有大多数类型实现的标准clone
函数,但无论出于何种原因,D都没有。我不知道为什么。但是,为自己的类型自己声明这样的功能仍然很容易。它不会出现在Object
上,它允许你在几乎任何类对象上使用它,而不用考虑你在Java和C#中可以做的实际类型。如果您愿意,您可以随时创建一个复制构造函数,但它不太灵活,因为您必须知道要复制的对象的类型,而使用clone
,它可以是从clone
类型派生的任何类型。 {1}}返回(对于Java和C#,它将是Object
但是你在D中决定的是什么,因为函数是非标准的。)
答案 1 :(得分:4)
是的,只需使用结构而不是类。
但是如果你想复制一个对象,那么你必须自己实现克隆。请注意,D设计师没有做到这一点;它在C#中完全相同,在Java中非常相似。目标是防止对象被过度复制,这被视为C ++的缺点(因为它在代码中非常隐藏)。
答案 2 :(得分:3)
即使在C ++中:
Foo Sorted(Foo Object)
没那么有用。如果对象已经排序并且您不需要创建副本怎么办?
在D中,您需要为您的课程提供clone()
部分内容,并在需要时调用。
否则使用Mehrdad提到的结构。
编辑:目前尚不清楚“复制对象”到底应该做什么。如果里面有对象数组,那么它会克隆那个数组吗?它包含的对象引用怎么样?实际上,D的作者Walter Bright先生默认不提供类实例的复制。