【问题标题】:Assignment Operator Overloading Java赋值运算符重载 Java
【发布时间】:2013-02-14 06:35:56
【问题描述】:

我无法弄清楚如何实现将 C++ 中的赋值运算符重载到 Java 的等价物。我知道没有这样的东西,但我需要模拟它。我试过重写 Clone() 函数,但没有运气。有什么想法吗?

以下是我的主要内容

 Queue p = new Queue();
 Queue q = new Queue();

    p.enqueue('a');
    p.enqueue(9);
    p.enqueue(10);
    p.enqueue(310);
    p.enqueue(8);

    q = p;
    System.out.print(p);

这里是克隆函数

public void Clone(Queue other) throws Throwable
{
    System.out.println("test\n");

    if(this == other)
    {

    }
    else
    {            
while(!isEmpty())
  dequeue();

Node tmp = other.head;
while(tmp != null){
    this.enqueue((T)tmp.element);
    tmp = tmp.next;

}   
    }

}

【问题讨论】:

  • clone() 与运算符重载有何关系?
  • 想要重载= 运算符的想法是非常可怕的。请浏览您自己的代码示例并思考为什么这会是一件非常非常糟糕的事情
  • @Aniket 它复制一个对象。复制对象通常是运算符重载的目的。这就是他们的关系。见Cloning

标签: java clone overloading variable-assignment operator-keyword


【解决方案1】:

Java 不支持运算符重载。

运算符重载违反了 Java 语言设计的核心原则之一:透明性。试图重载运算符是违反语言哲学的,应该避免......

【讨论】:

  • 我不是想重载运算符,我只是想用Java模拟它。
【解决方案2】:

在 Java 中无法实现运算符重载。它需要编译器的支持才能做到这一点。但是,您可以创建一个理解 java 语法的预处理器并在构建之前运行它,它将您的运算符的调用转换为适当的函数,但这只是矫枉过正。

clone 与运算符重载无关。

【讨论】:

  • 好的,那么您将如何使用“q = p”进行复制和对象并让它执行深度复制。因为当我运行该代码时,它会复制,但只是浅拷贝。所以两个对象都指向同一个对象。
  • 是的,这就是赋值运算符在 Java 中的工作方式。您不能覆盖该功能并使其进行深层复制。您可能想使用一个函数来做到这一点,或者像我回答的那样使用预处理器。
【解决方案3】:

您将需要编写一个显式的复制构造函数。在 Java 中,一切都是一个指针(或者他们称之为“引用”),所以当你将 p 分配给 q 时,你只是说 p 和 q 指向同一个对象。

q = new Queue(p)

是你想要的,假设你已经实现了适当的构造函数。

编辑: 使用语法“q = p”是不可能的。如果您想“模拟”赋值运算符,那么您将需要在 Queue 中编写一个新方法。例如,Java 程序员如何“模拟”重载加法运算符:

a.add(b);

因此,在您的情况下,您需要编写一个“分配”方法,该方法接受一个队列,复制其数据,并将这些副本分配给另一个对象的内部数据。

q.assign(p);

public void assign(Queue other) {
  this.primitive = other.primitive;
  this.someObject = new SomeObject(other.someObject);
}

这与您将获得的差不多。

【讨论】:

  • 是的,我已经实现了那个构造函数。它有效。但我的任务是在 C++ 到 Java 中实现等价的赋值运算符。
【解决方案4】:

没有“等价物”,因为您不能重载 Java 中的赋值运算符。您正在尝试使用 clone() 方法来模仿该行为,但您已经把它倒退了。如果没有运算符重载,您有三种选择:

  1. 编写一个函数,将调用对象变为传入对象的副本。
  2. 编写一个函数,复制调用对象并将其返回给将存储它的其他对象。
  3. 使用复制构造函数。

1。编写一个函数,将调用对象变为传入对象的副本。

请注意,这与赋值运算符重载相同,只是它被命名为“copy”而不是“operator="。

如果你想这样做:

foo A;
foo B;
A.copy(B);  // A is now a copy of B.

在 C++ 中:

foo& copy(const foo& rhs)
{
    if(&rhs != this)
    {
        this->m_someInt = rhs.m_someInt;
        this->m_someBar = rhs.m_someBar;
    }
    return *this;
}

在 Java 中:

foo copy(foo rhs)
{
    this.m_someInt = rhs.m_someInt;
    this.m_someBar.copy(rhs.m_someBar);
    return this;
}

请注意,在 C++ 中,将 this->m_someBar 分配给 rhs.m_someBar 按值复制 rhs.m_someBar,但在 Java 中,这样的分配会导致两个 foo 对象共享同一个 Bar 对象。因此,如果您不打算共享子主题,也必须在子主题上使用类似的复制机制。

2。编写一个函数,复制调用对象并将其返回给存储它的其他对象。

如果你想这样做:

foo A;
foo B;
A = B.clone();  // A is now a copy of B.

在 C++ 中:

foo clone() const  // Ignoring the fact that this is unnecessary in C++ where assignments (and returns) are by-value anyway.
{
    foo theCopy;
    theCopy.m_someInt = this->m_someInt;
    theCopy.m_someBar = this->m_someBar;
    return theCopy;
}

在 Java 中:

foo clone()
{
    foo theCopy = new foo();
    theCopy.m_someInt = this.m_someInt;
    theCopy.m_someBar = this.m_someBar.clone();
    return theCopy;
}

3。使用复制构造函数。

如果你想这样做:

foo B;
foo A = new foo(B);  // Java version
foo A(B); // C++ version

在 C++ 中:

foo(const foo& rhs)
  :m_someInt(rhs.m_someInt), m_someBar(rhs.m_someBar)
{
}

// Or optionally:
foo(const foo& rhs) = default;

在 Java 中:

foo(foo rhs)
{
    m_someInt = rhs.m_someInt;
    m_someBar = new Bar(rhs.m_someBar);
}

总之,您的问题是您尝试使用 clone() 的方式与我在上面使用 copy() 的方式相同。最接近等价物的是我的copy 方法。我个人的建议是只使用一个复制构造函数,然后就结束了。

【讨论】:

    【解决方案5】:

    如果您尝试覆盖 Object 上的 clone 方法,则它需要具有相同的签名(和大写)。你的方法签名是Clone(Queue)

    目前尚不清楚这与尝试模拟运算符重载有何关系,或者您要尝试重载的运算符...

    【讨论】:

      【解决方案6】:

      我来自 C++ 背景,所以我知道您来自哪里。 我认为这是您所追求的克隆方法。不要忘记实现 Cloneable 接口来告诉 'Object' 这个对象是一个可克隆对象。请参阅 Effective Java (2nd Ed) item 11 了解详细说明。

      【讨论】:

        猜你喜欢
        • 2018-05-13
        • 1970-01-01
        • 2013-03-30
        • 2016-08-30
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 2011-03-06
        • 2018-12-27
        相关资源
        最近更新 更多