Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass an object by value?

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.

like image 783
Maxpm Avatar asked Sep 25 '11 23:09

Maxpm


People also ask

How are objects passed by value in Java?

Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that's why it's called pass by value. Pass by Reference: An alias or reference to the actual parameter is passed to the method, that's why it's called pass by reference.

How do you pass an object variable?

To pass an object as an argument we write the object name as the argument while calling the function the same way we do it for other variables. Syntax: function_name(object_name); Example: In this Example there is a class which has an integer variable 'a' and a function 'add' which takes an object as argument.

Is object passed by value in C++?

Passing an object by value also means that any modifications made to the object, within the scope of the function being passed the object, will occur on the copied object and not on the object that was passed. This causes confusion for beginning C++ programmers as well as being a source of bugs!


2 Answers

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).

like image 165
Jonathan M Davis Avatar answered Nov 01 '22 00:11

Jonathan M Davis


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).

like image 38
user541686 Avatar answered Oct 31 '22 23:10

user541686