如何按值传递对象?

发布于 2024-12-06 14:01:59 字数 711 浏览 1 评论 0原文

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 structs. Is there such an equivalent for passing classes 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

把时间冻结 2024-12-13 14:01:59

类在设计上就是参考类型。它们不应该按值传递。这与 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 standard clone 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 on Object, 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 with clone, it can be any type derived from the type that clone returns (which would be Object in the case of Java and C# but would be whatever you decide in D, since the function is non-standard).

蝶…霜飞 2024-12-13 14:01:59

是的,只需使用结构而不是类。

但如果你想复制一个对象,那么你必须自己实现克隆。请注意,这并不是 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).

清浅ˋ旧时光 2024-12-13 14:01:59

即使在 C++ 中,这个:

Foo Sorted(Foo Object)

也没那么有用。如果对象已经排序并且您不需要创建副本怎么办?

在 D 中,您需要为您的类提供一些此类的 clone() 并在需要时调用它。

否则使用 Mehrdad 提到的结构。

编辑:尚不清楚“复制对象”到底应该做什么。如果它里面有对象数组,它应该克隆该数组吗?那么它包含的对象引用又如何呢? D 的作者 Walter Bright 先生没有默认提供类实例的复制,这实际上是件好事。

Even in C++ this:

Foo Sorted(Foo Object)

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文