为什么Java没有复制构造函数?
为什么 Java 不像 C++ 那样支持复制构造函数?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
为什么 Java 不像 C++ 那样支持复制构造函数?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
Java 确实如此。 它们只是不像 C++ 中那样被隐式调用,我怀疑这是你真正的问题。
首先,复制构造函数只不过是:
现在 C++ 将使用如下语句隐式调用复制构造函数:
在该实例中进行克隆/复制在 Java 中根本没有意义,因为所有 b1 和 b2 都是引用,而不是像它们那样的值对象在C++中。 在 C++ 中,该语句创建对象状态的副本。 在 Java 中,它只是复制引用。 对象的状态不会被复制,因此隐式调用复制构造函数是没有意义的。
这就是它的全部内容。
Java does. They're just not called implicitly like they are in C++ and I suspect that's your real question.
Firstly, a copy constructor is nothing more than:
Now C++ will implicitly call the copy constructor with a statement like this:
Cloning/copying in that instance simply makes no sense in Java because all b1 and b2 are references and not value objects like they are in C++. In C++ that statement makes a copy of the object's state. In Java it simply copies the reference. The object's state is not copied so implicitly calling the copy constructor makes no sense.
And that's all there is to it really.
来自 Bruce Eckel:
(我建议阅读整个页面 - 实际上,从这里开始。)
From Bruce Eckel:
(I recommend reading the entire page -- actually, start here instead.)
我认为这个问题的答案非常有趣。
其一,我相信在 Java 中所有对象都在堆上,虽然没有指针,但确实有“引用”。 引用具有复制语义,并且 java 在内部跟踪引用计数,以便其垃圾收集器知道可以安全地删除什么。
由于仅通过可复制引用访问对象,因此需要复制对象的实际次数大大减少(例如,在 C++ 中,仅将对象传递给函数(按值)会导致新对象被复制构造,在 Java 中)仅传递对该对象的引用)。 设计者可能认为clone()足以满足其余用途。
I think the answer to this is very interesting.
For one, I believe that in Java all objects are on the heap, and while you don't have pointers, you do have "References". References have copy symantics and java internally keeps track of reference counts so that its garbage collector knows whats safe to get rid of.
Since you only access objects through copyable references, the actual number of times you need to copy an object is greatly reduced (for example, in C++ just passing an object to a function (by value) results in new objects being copy constructed, in Java only the reference to the object is passed). The designers probably figured that clone() would be enough for the remaining uses.
这只是我的观点(我确信有一个合理的答案)
C++ 中的复制构造函数主要在按值发送或返回类实例时有用,因为此时复制构造函数被透明地激活。
由于在 Java 中,所有内容都是通过引用返回的,并且 VM 面向动态分配,因此确实没有理由考虑复制构造函数的复杂性。
此外,由于一切都是通过引用,因此开发人员通常必须提供自己的实现以及如何克隆字段的决定。
This is just my opinion (I am sure there is a justifiable answer)
Copy constructors in C++ are primarily useful when you are sending or returning instances of classes by value, since that is when the copy constructor is transparently activated.
Since in Java everything is returned by reference, and the VM is geared towards dynamic allocation, there really wasn't a justification for the complexities of a copy constructor.
In addition, since everything is by reference, a developer would often have to provide their own implementation and decision on how to clone fields.
我猜他们认为你可以只创建一个clone()方法来代替?
Guess they figured you can just make a clone() method instead?
确实如此。 当浅拷贝没问题时,你有 [clone()](http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone()) 以及当它们不是时你必须像C++一样实现深拷贝。
唯一的实质性区别是它是一个工厂方法而不是一个构造函数,但就灵活性和可测试性而言,这可能是一件好事。
It kind of does. When shallow copies are okay you have [clone()](http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone()) and when they aren't you have to implement a deep copy just like C++.
The only substantive difference is that it's a factory method rather than a constructor proper, but in terms of flexibility and testability that's probably a good thing.
我不是一个 C++ 程序员,但我似乎记得关于“三个朋友”的一条规则 - 复制构造函数、赋值运算符和析构函数。 如果您有一个,那么您可能需要全部三个。
那么也许语言中没有析构函数,他们不想包含复制构造函数? 只是一个猜测。
I'm not much of a C++ programmer, but I do seem to remember a rule about the "three amigos" - copy constructor, assignment operator, and destructor. If you have one, then you likely need all three.
So maybe without a destructor in the language, they didn't want to include a copy constructor? Just a guess.
嗯,可以。 它只是不会隐式创建。 如果我不得不猜测,这可能与 Java 对象始终是堆分配的事实有关。
在 C++ 中,默认的复制构造函数是逐成员浅复制。 如果一个类拥有在堆上分配的内存(通过原始指针),这将导致副本与原始类共享内部,这不是您想要的。
想象一下 Java 有这种行为。 任何具有对象字段(阅读:基本上所有字段)的类都会有错误的行为,并且您需要自己重写它。 99%的情况下,你没有给任何人省去任何麻烦。 此外,您刚刚为自己创建了一个微妙的陷阱 - 想象一下您不小心忘记覆盖默认的复制构造函数。 如果它是默认生成的,并且您尝试使用它,编译器根本不会抱怨,但您的程序在运行时会出现错误。
即使他们创建了一个执行深层复制的默认复制构造函数,我也不确定这是否特别有用。 无论如何,您不仅倾向于在 Java 中执行比 C++ 更少的副本,而且您并不总是希望深度复制字段。
您刚刚拥有的对象和您因需要而保留引用但不负责的对象是相同的 - 只是字段。 所有权和借贷并不是一流的概念。 对于您拥有的对象,您需要深度复制它们(除非它们是不可变的,在这种情况下您不应该打扰),而对于您只保存引用的对象,您需要复制引用。
我认为,盲目地深度复制所有内容的复制构造函数也不适合许多类。 不过,当然不仅仅是默认情况下的浅复制。
Well, it can. It just doesn't get created implicitly. If I had to guess, it's probably related to the fact that Java objects are always heap-allocated.
In C++, the default copy constructor is a member-wise shallow copy. If a class owns memory allocated on the heap (via a raw pointer), this will cause the copy to share internals with the original, which is not what you want.
Imagine for a moment that Java had this behavior. Any class that has fields that are objects (read: essentially all of them) would have the wrong behavior, and you'd need to override it yourself. For 99% of cases, you haven't saved anyone any trouble. Further, you've just created a subtle trap for yourself - imagine you accidentally forget to override the default copy constructor. If it was generated by default, and you try to use it, the compiler won't complain at all, but your program will misbehave at runtime.
Even if they made a default copy constructor that performs a deep copy, I'm not sure that would be particularly useful. Not only do you tend to perform fewer copies in Java than C++ anyway, but you don't always want to deep copy a field.
Objects that you just own, and objects that you hold references to because you need them, but aren't responsible for, are the same - just fields. Ownership and borrowing are not first class concepts. For objects you own, you'd want to deep copy them (unless they're immutable, in which case you shouldn't bother), and for objects you just hold a reference to, you want to copy the reference.
I would argue that a copy constructor that just mindlessly deep-copies everything wouldn't be suitable for many classes, either. Certainly more than shallow-copying by default, though.
Java有复制构造函数
注意:您可以编写 demo d2=d1,而不是 demo d2=new demo(d1)
黑白两个主要区别
demo d2=new demo(d1) 表示创建了新对象,并且它是
已分配内存但是
demo d2=d1意味着仅创建引用变量
它使用与对象d1相同的内存地址,因此d2未分配
分离的记忆。
复制构造函数的语法:
请参见下面第一个示例复制构造函数非常简单:))
classname(int datafield) //简单构造函数
{
this.datafield=datafield;
}
类名(类名对象)
{
datafield=object.datafield;//见下面的例子
}
现在可以打电话
{
类名 obj=new 类名();
classname anotherObject=obj;//或 classname anotherObject=new classname(obj)
}
Java have copy Constructor
Note:Instead of demo d2=new demo(d1) ,you can write demo d2=d1
Main difference b/w two
demo d2=new demo(d1) means new object is created and it is
allocated memory But
demo d2=d1 implies only reference variable is created
which uses the same memory address of object d1 and hence d2 not allocated
seperated memory.
Syntax of copy constructor:
See below Example first Copy constructor is very easy :))
classname(int datafield) //Simple Constructor
{
this.datafield=datafield;
}
classname(classname object)
{
datafield=object.datafield;//See below example
}
Now for Calling
{
classname obj=new classname();
classname anotherObject=obj;//or classname anotherObject=new classname(obj)
}