Я не понимаю, как работают конструкторы копирования - PullRequest
1 голос
/ 23 сентября 2019

Какова цель этого кода?

public Fraction(Fraction other) {
    num = other.num; 
    denom = other.denom; 
}

Если у вас есть конструктор, подобный этому:

public Fraction(int n, int d) {
    num = n;
    denom = d;
}

Почему вы должны инициализировать other.num в numи other.denom до denom.Что с синтаксисом конструктора копирования?Какова цель?

Ответы [ 4 ]

4 голосов
/ 23 сентября 2019

Гораздо удобнее использовать.


Если у вас есть простой конструктор, такой как:

public Fraction(int n, int d) {
    num = n;
    denom = d;
}

Вы можете скопировать оригинал экземпляра с помощью следующего кода:

Fraction copy = new Fraction(original.num, original.denom);

При использовании конструктора копирования вы выполняете следующий вызов:

Fraction copy = new Fraction(original);

Если у вас много параметров, это может быть гораздо удобнее.Что происходит, когда вы меняете аргументы вашего конструктора или вашего объекта?Без конструктора копирования вы должны изменить все такие вызовы.


Примечательный факт из M.Комментарий Прохорова:

Специального синтаксиса для конструкторов копирования не существует, это просто логический стиль реализации параметризованного конструктора.

2 голосов
/ 23 сентября 2019

Если бы вы просто набрали

public Fraction(Fraction other) {
}

Java не просто догадывается, что вы хотите скопировать значения other в новый объект.Java автоматически не инициализирует ваши переменные для вас.Чтобы это был конструктор копирования, вам все равно придется вручную напечатать код, который копирует поля из other в создаваемый вами объект.Например:

public Fraction(Fraction other) {
    num = other.num; 
    denom = other.denom; 
}

Конструктор создает новый Fraction, но именно код, который вы вводите внутри, вручную выполняет «копирование», что делает его «конструктором копирования» и позволяет вам делать

Fraction a = Fraction(4, 20);
Fraction b = new Fraction(a); 
// b has the same values as a but is a different object

Конечно, если у вас уже есть другой конструктор, более короткий способ создать конструктор копирования -

public Fraction(int n, int d) {
    num = n; 
    denom = d; 
}

public Fraction(Fraction other) {
    this(other.num, other.denom);
}
1 голос
/ 23 сентября 2019

Если у вас есть экземпляр объекта Fraction, например:

Fraction fr = new Fraction(1, 2); //represents 1/2

Конечно, вы можете скопировать , просто назначив его новомупеременная:

Fraction copy = fr;

Но теперь и fr, и copy указывают на один и тот же объект (одно и то же место в памяти).Если по какой-либо причине copy изменится на 1/3, fr также изменится.Иногда вам нужна совершенно новая копия вашего оригинального объекта.Вот где действительно удобно написать:

Fraction copy = new Fraction(fr);

Теперь вы можете самостоятельно манипулировать copy и fr, не беспокоясь о нежелательных изменениях в любом из них.

Вы можете прочитать это учебное пособие для получения более подробной информации по предмету.

1 голос
/ 23 сентября 2019

Есть 2 веские причины для использования конструктора копирования вместо конструктора, передающего все параметры:

  1. когда у нас сложный объект со многими атрибутами, удобно использовать конструктор копирования
  2. если мы добавим атрибут в существующий класс, то мы можем просто изменить конструктор копирования, чтобы учесть этот новый атрибут, вместо того, чтобы изменять каждое вхождение другого конструктора
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...