如何按值传递对象?
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 的函数进行引用传递。是否存在按值传递类的等效方法?
例如,假设我想要创建一个返回自定义容器类的排序副本的函数 function。在 C++ 中,这就像使用 Foo Sorted(Foo Object)
一样简单,而不是 Foo Sort(Foo& Object)
。我认为如果不手动复制对象,就无法在 D 中执行此操作。
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."
}
In D, reference vs. value is a trait of the type, rather than of the function parameter. Coming from C++, this feels really bad to me.
It looks like there's a ref
keyword to force pass-by-reference for functions accepting struct
s. Is there such an equivalent for passing class
es by value?
For example, let's say I want to make a function function that returns a sorted copy of a custom container class. In C++, that's as simple as using Foo Sorted(Foo Object)
, as opposed to Foo Sort(Foo& Object)
. I see no way of doing this in D without manually copying the object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
类在设计上就是参考类型。它们不应该按值传递。这与 Java 和 C# 完全相同。然而,与 Java 和 C# 不同,D 也具有成熟的用户定义值类型,因为它具有结构(C# 也具有结构,但它们更加受到限制)。 C++ 将两者混为一谈会导致诸如对象切片之类的问题。
现在,显然有时您想要复制引用类型。解决方案是克隆。您为您的类提供一个
clone
函数,该函数返回所调用对象的副本。这样,您可以在需要时复制它,并且仅在您需要时才会复制它。 Java 和 C# 有一个大多数类型都实现的标准clone
函数,但出于某种原因 D 没有实现。我不知道为什么。但为您自己的类型自行声明这样的函数仍然很容易。它只是不会出现在Object
上,这将允许您在几乎任何类对象上使用它,而无需关心实际类型就像您在 Java 和 C# 中可以执行的操作一样。如果您愿意,您始终可以创建一个复制构造函数,但它不太灵活,因为您必须知道要复制的对象的类型,而使用clone
时,它可以是从clone
返回的类型(在 Java 和 C# 中将是Object
,但在 D 中将是您决定的任何内容,因为该函数是非标准的)。Classes are reference types by design. They're not supposed to be passed by value. It's exactly the same with Java and C#. However, unlike Java and C#, D has full-fledged user-defined value types as well, since it has structs (C# has structs too, but they're much more limited). The fact that C++ conflates the two causes problems such as object slicing.
Now, obviously there are times when you want to copy a reference type. The solution to that is cloning. You give your class a
clone
function which returns a copy of the object it's called on. That way, you can copy it when you need to, and it only gets copied when you need it to be. Java and C# have a standardclone
function that most types implement, but for whatever reason D does not. I'm not sure why. But it's still easy enough to declare such a function yourself for your own types. It just isn't going to be onObject
, which would allow you to use it on pretty much any class object without caring what the actual type was like you can do in Java and C#. You could always create a copy constructor instead, if you prefer, but it's less flexible, because you have to know the type of the object being copied, whereas withclone
, it can be any type derived from the type thatclone
returns (which would beObject
in the case of Java and C# but would be whatever you decide in D, since the function is non-standard).是的,只需使用结构而不是类。
但如果你想复制一个对象,那么你必须自己实现克隆。请注意,这并不是 D 设计师编造的;而是由 D 设计师编造的。这在 C# 中是完全相同的,在 Java 中也非常相似。目标是防止对象被过度复制,这被视为 C++ 的缺点(因为它非常隐藏在代码中)。
Yeah, just use a struct instead of a class.
But if you want to copy an object, then you have to implement cloning yourself. Note that the D designers didn't make this up; it's the exact same way in C#, and pretty similar in Java. The goal is to prevent objects from being copied excessively, which is seen as a downside of C++ (since it's very hidden in the code).
即使在 C++ 中,这个:
也没那么有用。如果对象已经排序并且您不需要创建副本怎么办?
在 D 中,您需要为您的类提供一些此类的
clone()
并在需要时调用它。否则使用 Mehrdad 提到的结构。
编辑:尚不清楚“复制对象”到底应该做什么。如果它里面有对象数组,它应该克隆该数组吗?那么它包含的对象引用又如何呢? D 的作者 Walter Bright 先生没有默认提供类实例的复制,这实际上是件好事。
Even in C++ this:
is not that useful. What if the Object is already sorted and you don't need to create a copy?
In D you will need to provide
clone()
of some such for your class and call it if needed.Otherwise use structs as Mehrdad mentioned.
Edit: It is not clear what exactly "copying the object" should do. If it has array of objects inside shall it clone that array? And what about object references it contains? It is actually good that monsieur Walter Bright, author of D, did not provide copying of class instances by default.