9

I am trying to write some codes that a variable can be added up by other class's function as testing for some works. I do not want to write return, extends, global variable but still can add the value. Any Ideas? Or is it impossible?

void main() {
  bbb B = new bbb();
  B.bOut();
  
}
class bbb{
  int b = 1;
  void bOut(){
    aaa A = aaa(this.b);
    A.aAdd();
    print(b);
  }
}
class aaa{
  int variableA;
  aaa(this.variableA);
  void aAdd (){
    variableA++;
  }
}

The output is 1

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Wesley Yam
  • 101
  • 1
  • 1
  • 3

3 Answers3

16

Dart passes-by-value where the value is a reference to the object

As jamesdlin said:

I would consider Dart to be like many object-oriented languages in that it is always pass-by-value and that the value of an object is a reference to it. In a true pass-by-reference system, a callee can modify variables in the caller (as with C++'s reference parameters).

What does that mean?

Say I write my home address on a piece of paper and give it to you. If you go away and tear up the paper or cross out the address and write a different one, that doesn't change my home or my address. I still have the same home and the same address no matter what you do to the piece of paper I gave you.

However, if you use the address that I wrote on the paper to find my home, you could paint the building or take away the trash or plant a flower. That would change some things about my home, but it wouldn't change the address.

It's the same thing with Dart. You can pass a variable off as an argument to some function. If the object that the variable refers to is mutable, the function can change the state of the object, but it can't change where that object is stored in memory.

Example

Here is the Dart version of the story above, inspired from this Java example.

void main() {
  Home addressToMyHome = Home('blue');
  Home myAddressCopy = addressToMyHome;

  print('My home is ${addressToMyHome.color}.');
  
  print('Here is my address.');
  writeNewAddressOnPaper(addressToMyHome);
  print('But my home is still ${addressToMyHome.color}.');

  print('Here is my address again.');
  goToMyHomeAndPaintIt(addressToMyHome);
  print('Now my home is ${addressToMyHome.color}.');
  
  if (addressToMyHome == myAddressCopy) {
    print('My address has not changed, though.');
  }
}

void writeNewAddressOnPaper(Home home) {
  home = Home('purple');
  print('You made a new ${home.color} home.');
}

void goToMyHomeAndPaintIt(Home home) {
  home.color = 'purple';
  print('You are painting my home ${home.color}.');
}

class Home {
  String color;
  Home(this.color);
}

This prints the following story:

My home is blue.
Here is my address.
You made a new purple home.
But my home is still blue.
Here is my address again.
You are painting my home purple.
Now my home is purple.
My address has not changed, though.

Note that the variable addressToMyHome does not contain the Home object itself, but only a value of where the Home object is stored in memory.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 1
    I don't think the value of the variable is the actual memory address, but rather Dart uses the value somehow to reference the object in memory. I'm unclear on the specifics of that. – Suragch Jul 30 '20 at 10:53
9

Welcome to SO Wesley!

In Dart, as in many other object oriented programming languages, objects are always pass-by-value. But you can still pass pointers to objects and arrays by value. Thanks to @jamesdlin for pointing that out in the comments. For an more indepth look on this subject: Is Java pass-by-reference or pass-by-value?

Instead of passing this.b you could simply pass a reference to the object: bbb and access the variable b. I've prepared a simple example:

Output:

0
1

Code:

class Wrapper {
  int i;
}

test() {
  Wrapper wrapper = Wrapper();

  wrapper.i = 0;
  print(wrapper.i);

  increase(wrapper);
  print(wrapper.i);
}

increase(Wrapper wrapper) {
  wrapper.i++;
}
NiklasPor
  • 9,116
  • 1
  • 45
  • 47
  • Thank you for your help. If using the posed structure as question and in Class bbb`int b = 1` changes to `String b = "B"` and Class aaa: `String variableA ; void aAdd(){variableA = "A"}`, what is the solution? Because in my real problem, I have a class A which depends on the dropDownButton's selected option in class B to call the respected data in firestore. Thank you :) ! – Wesley Yam Aug 03 '19 at 15:21
  • 5
    I would consider Dart to be like [many object-oriented languages](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) in that it is always pass-by-*value* and that the *value* of an object is a *reference* to it. In a true pass-by-reference system, a callee can modify variables in the caller (as with C++'s reference parameters). – jamesdlin Aug 03 '19 at 15:55
  • Thanks @jamesdlin, what I was taught at university wasn't accurate enough. Always happy to be corrected :) I'll edit my answer - the concept should still work. – NiklasPor Aug 03 '19 at 16:01
2

Disclaimer: I's a total newbie at Dart (about 3 days of juggling and still on the first few pages of the the specs) but coming from C# I've made the simplest test:

class Obj {
    String s1;
}

class Outer {
    Obj obj;

    Outer() {
        obj = Obj();
        obj.s1 = "Stuff";
    }

    void passValueToInner() {
        var inner = Inner();
        print("Obj.s1 = ${obj.s1}");
        inner.changeObj(obj);
        print("Obj.s1 = ${obj.s1}");
    }
}

class Inner {
    void changeObj(Obj obj) {
        obj.s1 = "OtherStuff";
        obj = null;
    }
}

It prints:

Outer.Obj.s1 = Stuff
Obj is null? true
Outer.Obj.s1 = OtherStuff

So, it appears that objects are not really passed by reference in the sense of C/C++ and others. Dart passes a new handle pointing to the object in memory (or managed vector, whatever... newbie remember...) into the called method/function. That's why it acts like byRef if you change it. When you null-it, you are only acting on the handle.

CalomanX
  • 21
  • 1