Почему Java не поддерживает конструктор копирования, как в C++?Почему Java не имеет конструктора копирования?
ответ
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 он просто копирует ссылку . Состояние объекта не копируется, поэтому неявное обращение к конструктору копирования бессмысленно.
И это все, что есть на самом деле.
+1. В то время как остальные из нас были напуганы об иерархиях объектов, вы перешли прямо к синтаксису и, вероятно, ответили на вопрос * реального * OP, пока вы это делали. –
Это отличное объяснение. Спасибо! – Cuga
Возможно, вы захотите отредактировать задание; вы назначаете b2 себе. Кроме того, «statemen tlike» имеет место в неправильном месте. –
Угадайте, что они решили, что вы можете просто сделать метод clone()?
Я думаю, что ответ на этот вопрос очень интересный.
Во-первых, я считаю, что в Java все объекты находятся в куче, и пока у вас нет указателей, у вас есть «Ссылки». В ссылках есть копия symantics, и Java внутренне отслеживает количество ссылок, чтобы сборщик мусора знал, что можно избавиться.
Поскольку вы только получаете доступ к объектам с помощью копируемых ссылок, фактическое количество раз, когда вам нужно скопировать объект, значительно уменьшается (например, на C++ просто передача объекта функции (по значению) приводит к тому, что новые объекты копируются построенный, в Java передается только ссылка на объект). Дизайнеры, вероятно, полагали, что для остальных применений будет достаточно clone().
Согласен. Конструктор копирования действительно решает проблемы управления памятью на C++. – alphazero
Downvoted, потому что: * Java не использует семантику копирования (для объектов). Передача объекта вокруг не клонирует или не копирует объект, а также не изменяет количество ссылок - он просто передает ссылку. * Слишком много путаницы между семантикой копирования и фактом копирования ссылки на этот объект. – Arafangion
В C++ вы должны передавать эти объекты указателем или ссылкой, чтобы минимизировать избыточное копирование. Это не проблема управления памятью, это просто (небольшие) синтаксические различия в языках, когда вы хотите сделать глубокую копию объекта. –
Это только мое мнение (я уверен, что есть обоснованный ответ)
Конструкторы копирования в C++ в основном используется при отправке или возвращать экземпляры классов по значению, так как это когда конструктор копирования прозрачно активирован.
Поскольку в Java все возвращается по ссылке, а виртуальная машина ориентирована на динамическое распределение, на самом деле не было оправдания сложностей конструктора копирования.
Кроме того, поскольку все по ссылке, разработчику часто приходилось предоставлять свою собственную реализацию и решение о том, как клонировать поля.
Это как будто. Когда мелкие копии в порядке, у вас есть [clone()] (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone()), и когда их нет, вам нужно реализовать глубокую копию, как C++.
Единственное существенное отличие состоит в том, что это заводский метод, а не собственный конструктор , но с точки зрения гибкости и тестируемости это, вероятно, хорошо.
Я не очень программист на C++, но, похоже, я помню правило о «трех амигах» - конструкторе копирования, операторе присваивания и деструктор.Если у вас его есть, то вам, вероятно, понадобятся все три.
Так что, может быть, без деструктора на языке, они не хотели включать в себя конструктор копий? Просто гадать.
Не совсем. В C++ это больше похоже: если вам нужен один из трех (скажем, конструктор копирования), то вам, скорее всего, понадобятся и другие два, хотя вы не можете этого понять в то время. –
Кроме того, если они вам не нужны, вы должны объявить их закрытыми и не выполнять их.Это заставит компилятор заменить свою собственную «мелкую» копию ... – dicroce
От Bruce Eckel:
Почему [конструктор копирования] работает в C++, а не Java?
Конструктор копирования является фундаментальной частью C++, так как он автоматически создает локальную копию объекта. Тем не менее приведенный выше пример доказывает, что он не работает для Java. Зачем? В Java все, что мы манипулируем, это дескриптор , в то время как на C++ вы можете иметь дескрипторных объектов, и вы также можете обходить объекты напрямую. Это то, что конструктор копии C++ предназначен для: когда вы хотите взять объект и передать его по значению, таким образом, дублирует объект. Поэтому он работает отлично в C++, но вы должны держать в умом, что эта схема не работает в Java, , поэтому не используйте ее.
(я рекомендую прочитать всю страницу - на самом деле, начать here вместо этого.)
Java имеет скопировать Конструктор
Примечания: Вместо дема d2 = новый демо (d1), вы можете написать дема d2 = d1
Основного различия в ч/б два
демы d2 = новых демонстрационные (d1) означает, создается новый объект, и это выделенная память Но
демонстрационных d2 = d1 означает ссылаться только переменный создаются , который использует один и тот же адрес памяти объекта d1 и, следовательно, d2 не выделено отдельная память.
Синтаксис конструктора копирования:
Ниже Пример первый конструктор копирования очень просто :))
имя_класса (интермедиат DataField) // Простой конструктор
{
this.datafield = DataField;
}
имя_класса (имя_класса объект)
{
DataField = объект.DataField; // См ниже пример
}
Теперь для вызова
{
имя_класса OBJ = новый Classname();
имя_класса anotherObject = OBJ; // или имя_класса anotherObject = новый имя_класса (объект)
}
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()); } }
Ну, может. Он просто не создается неявно. Если бы я должен был догадаться, это, вероятно, связано с тем, что объекты Java всегда выделены в виде кучи.
В C++ конструктор копии по умолчанию является мелкой по размеру копией. Если класс владеет памятью, выделенной в куче (через необработанный указатель), это заставит копию совместно использовать оригиналы с оригиналом, чего вы не хотите.
Представьте себе, что Java имеет такое поведение. Любой класс, у которого есть поля, которые являются объектами (читай: по сути, все они), будет иметь неправильное поведение, и вам нужно будет переопределить его самостоятельно. В 99% случаев вы никому не помогли. Кроме того, вы просто создали тонкую ловушку для себя - представьте, что вы случайно забыли переопределить конструктор копии по умолчанию. Если он был создан по умолчанию, и вы пытаетесь его использовать, компилятор вообще не будет жаловаться, но ваша программа будет плохо себя вести во время выполнения.
Даже если они сделали конструктор копии по умолчанию, который выполняет глубокую копию, я не уверен, что это было бы особенно полезно. Мало того, что вы, как правило, выполняете меньше копий на Java, чем C++, но вы не всегда хотите, чтобы скопировать поле.
Объекты, которыми вы владеете, и объекты, на которых вы держите ссылки, потому что они вам нужны, но не отвечают за, являются одинаковыми - просто поля. Собственность и заимствование не являются понятиями первого класса. Для объектов, которые у вас есть, вы хотите их глубоко скопировать (если они не являются неизменными, и в этом случае вам не следует беспокоиться), а для объектов, на которые вы просто держите ссылку, вы хотите скопировать ссылку.
Я бы сказал, что конструктор копирования, который просто бездумно глубоко копирует все, не подходит для многих классов. Конечно, более чем мелкое копирование по умолчанию.
Это отличные объяснения, благодаря всем! – Cuga
Также читайте «Что случилось с конструкторами копирования? Зачем использовать интерфейс Clonable?» http://stackoverflow.com/questions/388304/whats-wrong-with-copy-constructors-why-use-cloneable-interface –