Search code examples
javac++methodscall

How to take a copy in method call - C++ and Java differences


I have some code in C++

struct Node {
    int x;

    Node(int x) : x(x) {}

    friend std::ostream & operator << (std::ostream &o, const Node &n) {
        o << n.x;
        return o;
    }
};

void Foo(Node n) {
    n.x--;
    cout << "Foo: " << n << endl;
}

void Foo2(Node &n) {
    n.x--;
    cout << "Foo2: " << n << endl;
}

int main() {
    Node n(5);
    cout << n << endl;
    Foo(n);
    cout << n << endl;
    Foo2(n);
    cout << n << endl;

    return 0;
}

...and the output is

5
Foo: 4
4
Foo2: 3
4

...now I reached the same in Java

class Node {
    public int x;

    Node(int x) {
        this.x = x;
    }

    @Override
    public String toString() {
        return Integer.toString(x);
    }
}

public class NodeHomevork {
    static void Foo(Node n) {
        n.x--;
        System.out.println("Foo: " + n);
    }

    static void Foo2(Node n) {
        Node n2 = new Node(n.x);
        n2.x--;
        System.out.println("Foo2: " + n2);
    }

    public static void main(String[] args) {
        Node n = new Node(5);
        System.out.println(n);
        Foo(n);
        System.out.println(n);
        Foo2(n);
        System.out.println(n);
    }
}

But I don't know how to implement Foo2 without using new keyword inside Foo2. If you have any ideas I'll be grateful for any posts, thanks.


Solution

  • In C++ when you put an argument to Foo2 your object is copied. In Java you can use clone() method:

    class Node implements Cloneable
    {
        public int x;
    
        Node(int x) { this.x = x; }
    
        @Override
        public String toString() { return Integer.toString(x); }
    
        @Override
        protected Node clone() throws CloneNotSupportedException
        {
            Node copy = null;
            copy = (Node)super.clone();
            return copy;
        }
    }
    

    Foo2 code:

    static void Foo2(Node n)
    {
        Node n2 = n.clone();
        n2.x--;
        System.out.println("Foo2: " + n2);
    }
    

    OR:

    @Override
    public Node clone() throws CloneNotSupportedException { ... } //public!
    
    static void Foo2(Node n)
    {
        n.x--;
        System.out.println("Foo2: " + n);
    }
    

    And call via Foo2(n.clone()); But I think you should use first option, because in C++ code your clone is inside method.