【问题标题】:How to take a copy in method call - C++ and Java differences如何在方法调用中获取副本 - C++ 和 Java 的区别
【发布时间】:2017-06-06 12:50:49
【问题描述】:

我有一些 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;
}

...输出是

5
Foo: 4
4
Foo2: 3
4

...现在我在 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);
    }
}

但是我不知道如何在 Foo2 中不使用 new 关键字来实现 Foo2。如果您有任何想法,我将不胜感激任何帖子,谢谢。

【问题讨论】:

  • Java 是一种引用类型语言。当你想创建一个变量时,没有办法避免newC# 具有 structs,它们是值类型。这意味着您可以在不使用 new 的情况下创建 structs 的变量。另一方面,C++ 完全是一种值类型语言,C++ 性能优越的原因之一是值类型。
  • 可能dupe ?如果不是,则高度相关。唯一要补充的是,java中只存在引用值传递。
  • 您可以将new 移动到其他地方。最干净的解决方案是在你的类中添加一个像Node newInstanceFromExisting(Node node) 这样的静态方法,这样Foo2 就会说Node n2 = Node.newInstanceFromExisting(n);。然后new 将在newInstanceFromExisting 内。
  • Java 不是 C++,C++ 不是 Java。不要尝试以Java为模型编写C++代码,也不要尝试以C++为模型编写Java代码。
  • @Владимир 我不知道“老师”要你做什么。我的意思是 Java 和 C++ 是两种不同的语言,通过逐行翻译来从一种语言转换到另一种语言是行不通的。

标签: java c++ methods call


【解决方案1】:

在 C++ 中,当您将参数传递给 Foo2 时,您的对象会被复制。在 Java 中,您可以使用 clone() 方法:

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 代码:

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

或者:

@Override
public Node clone() throws CloneNotSupportedException { ... } //public!

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

并通过Foo2(n.clone()); 拨打电话 但我认为您应该使用第一个选项,因为在 C++ 代码中,您的克隆位于方法内部。

【讨论】:

  • 通常当您覆盖 clone 时,您会将其访问权限提升到 public
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多