为什么 Java 不像 C++ 那样支持复制构造函数?

有帮助吗?

解决方案

Java确实如此。他们只是不像C ++那样被隐式调用,我怀疑这是你真正的问题。

首先,复制构造函数只不过是:

public class Blah {
  private int foo;

  public Blah() { } // public no-args constructor
  public Blah(Blah b) { foo = b.foo; }  // copy constructor
}

现在C ++将使用如下语句隐式调用复制构造函数:

Blah b2 = b1;

在该实例中克隆/复制在Java中没有任何意义,因为所有b1和b2都是引用而不是像C ++中那样的值对象。在C ++中,该语句复制了对象的状态。在Java中,它只是复制引用。不会复制对象的状态,因此隐式调用复制构造函数是没有意义的。

这就是真的。

其他提示

来自 Bruce Eckel

  

为什么[复制构造函数]在C ++而不是Java中工作?

     

复制构造函数是一个基础   C ++的一部分,因为它是自动的   制作对象的本地副本。然而   上面的例子证明了它的确如此   不适合Java。为什么?在Java中   我们操纵的一切都是   处理,而在C ++中你可以拥有   类似于句柄的实体,你也可以   直接绕过对象。   这就是C ++拷贝构造函数   适用于:当你想要一个   对象并通过值传递它,因此   复制对象。所以它有效   在C ++中很好,但你应该继续   请注意,此方案在Java中失败,   所以不要使用它。

(我建议阅读整个页面 - 实际上,请改为此处 。)

我认为答案非常有趣。

首先,我相信在Java中所有对象都在堆上,虽然你没有指针,但你确实有“引用”。引用具有复制语义,java在内部跟踪引用计数,以便其垃圾收集器知道什么是安全的。

由于您只通过可复制引用访问对象,因此大大减少了复制对象所需的实际次数(例如,在C ++中只是将对象传递给函数(按值)会导致新对象被复制构造,在Java中只传递对象的引用)。设计师可能认为clone()足以满足其余用途。

 

这只是我的意见(我确信有合理的答案)

当您按值发送或返回类的实例时,C ++中的复制构造函数非常有用,因为这是透明激活复制构造函数的时候。

因为在Java中,所有东西都是通过引用返回的,而VM是面向动态分配的,所以复制构造函数的复杂性确实没有理由。

此外,由于所有内容都是通过引用,开发人员通常必须提供自己的实现和决定如何克隆字段。

猜猜他们认为你可以改为制作一个clone()方法吗?

有点像。当浅拷贝可以,你有[clone()]( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone())当他们不是你必须像C ++一样实现深层拷贝。

唯一的实质性区别是它是一种工厂方法而不是构造函数,但在灵活性和可测试性方面可能是一件好事。

我不是一个C ++程序员,但我似乎记得关于“三个朋友”的规则。 - 复制构造函数,赋值运算符和析构函数。如果你有一个,那么你可能需要这三个。

所以也许没有语言中的析构函数,他们不想包含复制构造函数?只是一个猜测。

嗯,它可以。它不是隐式创建的。如果我不得不猜测,那可能与Java对象总是堆分配有关。

在C ++中,默认的复制构造函数是一个成员浅的副本。如果一个类拥有在堆上分配的内存(通过原始指针),这将导致副本与原始内容共享内部,这不是您想要的。

想象一下Java有这种行为。任何具有对象字段的类(读取:基本上都是它们)将具有错误的行为,并且您需要自己覆盖它。对于99%的案例,您没有任何人遇到任何麻烦。此外,您刚刚为自己创建了一个微妙的陷阱 - 想象您不小心忘记覆盖默认的复制构造函数。如果它是默认生成的,并且您尝试使用它,编译器根本不会抱怨,但是您的程序在运行时会出错。

即使他们制作了执行深层复制的默认复制构造函数,我也不确定它会特别有用。不管怎样,你不仅要在Java中执行比C ++更少的副本,而且你并不总是想要深度复制字段。

你刚才拥有的对象,以及你所拥有的对象,因为你需要它们,但不负责,是相同的 - 只是字段。所有权和借款不是一流的概念。对于你拥有的对象,你需要深层复制它们(除非它们是不可变的,在这种情况下你不应该打扰),对于你只是持有引用的对象,你想要复制引用。

我认为复制构造函数只是盲目地复制所有内容,也不适合许多类。当然,默认情况下不仅仅是浅层复制。

爪哇 复制构造函数
注意:代替 演示 d2=新演示(d1) ,你可以写 演示 d2=d1
两者主要区别
演示 d2=新演示(d1) 意味着创建新对象,并且是分配的内存,但是
演示 d2=d1 暗示创建仅创建参考变量,该变量使用对象的相同内存地址 d1 因此 d2 未分配分开的内存。

复制构造函数的语法:
见下文 第一个示例复制构造函数非常简单:))
classname(int datafield) //简单构造函数
{
this.datafield=datafield;
}

类名(类名对象)
{
datafield=object.datafield;//见下面的例子
}
现在可以打电话
{

类名 obj=new 类名();

classname anotherObject=obj;//或 classname anotherObject=new classname(obj)

}

 class demo
{
    private int length;

    private int breadth;

    private int radius;

    demo(int x,int y)

    {
        length=x;
        breadth=y;
    }
    int area()
    {
        return length*breadth;
    }

    //Copy Constructor
    demo(demo obj)
    {
        length=obj.length;
        breadth=obj.breadth;
    }


    public static void main(String args[])
    {
        demo d1=new demo(5,6);
        demo d2=new demo(d1);//Invokes Copy Constructure
        System.out.println("Area for d1 object="+d1.area());
        System.out.println("Area for d2 object="+d2.area());

    }
}

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top