题
为什么 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()); } }