Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Копирование и присваивание часть первая  (Прочитано 13369 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Alf
Гость
« : 23-03-2005 08:49 » 

Поскольку не являюсь экспертом в C++, при чтении возникли вопросы. Хотелось бы прояснить некоторые детали.

1.
Цитата
Конструктор копий произвольного класса X выглядит так:
Х(const X&) ; // конструктор копий класса Х
...skipped...
Аргумент в целом читается как "постоянная ссылка на X".

IMHO здесь все же ссылка на константу ("ссылка на постоянный X"), а не константная ссылка. "Постоянная ссылка на X" по идее должна выглядеть как
Код:
X& const

2.
Цитата
class POINT
{
public:
POINT() { X=0; Y=0; } //конструктор по умолчанию
POINT(int a, int b) { X=a; Y=b; } //еще конструктор
POINT(const POINT& Pixel) { X=Pixel.X; Y=Pixel.Y; } //конструктор
//копирования
int X; //координаты точки
int Y;
};

Поскольку основная задача конструктора - создание и инициализация объекта, IMHO корректнее было бы построить конструктор копирования через инициализацию переменных-членов класса, а не через присваивание:
Код:
POINT(const POINT& Pixel):  X(Pixel.X), Y(Pixel.Y) { }
Вообще статья много выиграет, если в нее добавить обсуждение некоторых тонкостей, касающихся отличия инициализации от присваивания.

3.
Цитата
class X
{
public:
Х(); // конструктор по умолчанию
virtual ~X(); // виртуальный деструктор
// Конструктор копии и операция присваивания не определены
// намеренно. Класс содержит только данные, размещаемые
// в стеке, поэтому предопределенных конструктора копий
//и операции присваивания достаточно.
private:
int data;
char moreData;
float no_Pointers;
};

Не согласен с выделенной частью комментария. Сам класс не может содержать данных, если они не объявлены как статические (в данном случае этого нет). Данные содержит экземпляр класса, а уж где эти данные разместятся при его инстанцировании, зависит от программиста. Например, если он решит создать экземпляр таким образом:
Код:
X* px = new X();
, то размещены данные будут не в стеке, а в куче.

4. Имеет смысл добавить в статью рассмотрение "глубокого" и "мелкого" копирования, поскольку данный вопрос имеет непосредственное отношение к теме статьи.
« Последнее редактирование: 23-03-2005 08:52 от Alf » Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 24-03-2005 04:49 » 

Цитата
Поскольку не являюсь экспертом в C++
Судя по вопросам к этой и предыдущей статьям, вы, батенька, того-с, слегка лукавите Отлично
Это у меня при подготовке ответов возникают вопросы, требующие уточнений по литературе...
Цитата
IMHO здесь все же ссылка на константу
Согласен, упустил... Трудности перевода + невнимательность = результат Отлично
Цитата
IMHO корректнее было бы построить конструктор копирования через инициализацию переменных-членов класса, а не через присваивание
И то и другое равноправно имеет право на жизнь. Такой вариант нагляднее в смысле обучения, показательнее что-ли... Но это уже мое IMHO... А "по жизни" я и сам чаще применяю инициализацию Улыбаюсь
Цитата
то размещены данные будут не в стеке, а в куче.
Ну, если рассматривать примеры и варианты "на все случаи жизни", то ни жизни, ни объемов толстенной книги не хватит Отлично
Смысл достаточности для ТАКОГО класса предопределенных конструкторов копирования и операции присваивания не меняется от того как именно будет создан объект. А с выделенным комментарием можно согласиться. Да не класс, объект. Можно, наверное было написать "класс описывает... при условии что..."
Цитата
Имеет смысл добавить в статью рассмотрение "глубокого" и "мелкого" копирования
В следующей части (а их впереди еще три, и все уже давно написаны) будет рассмотрено буквальное и развернутое копирование - это не оно? А то терминов расплодилось немеряно Отлично
« Последнее редактирование: 24-03-2005 04:55 от Михалыч » Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Alf
Гость
« Ответ #2 : 24-03-2005 08:11 » 

И то и другое равноправно имеет право на жизнь.

Не согласен. Вполне может встретиться вариант, когда инициализация и присваивание неравнозначны. Например, класс описывает данные о сотрудниках некоторой организации, при этом по бизнес-правилам табельный номер не может меняться. Вполне естественно предоставить доступ к этому полю только на чтение, а значение задавать при инициализации. Если теперь сделаем, скажем, класс "менеджер" производным от "сотрудника", то такой вариант сработает:
Код:
class CWorker
{
private:
  long int m_OrdNum;
...
public:
  CWorker(long int n) { m_OrdNum = n; };
  long int GetOrdNum() { return m_OrdNum; };
...
}

class CManager: public CWorker
{
public:
  CManager(long int n): CWorker(n) { ... };
...
}

Как сделать то же самое посредством присваивания столь же просто и безопасно, я так с ходу и не представляю.

Такой вариант нагляднее в смысле обучения, показательнее что-ли...

Сначала научить присваивать, а потом переучивать корректно инициалировать? IMHO все же лучше сразу учить правильно, даже если это немного сложнее. Тем более что все-таки присваивание все же не всесильно, как показано в примере выше.

Но это уже мое IMHO... А "по жизни" я и сам чаще применяю инициализацию Улыбаюсь

Тем более, самое лучшее обучение - личным примером  Улыбаюсь

Ну, если рассматривать примеры и варианты "на все случаи жизни", то ни жизни, ни объемов толстенной книги не хватит Отлично

В данном случае как раз все просто. Достаточно лишь удалить выделенный фрагмент, который может сбить начинающего с толку, и все остальное становится совершенно корректным в любом случае, вовсе не потребуется перебор частных случаев. Тут как раз та ситуация, что излишняя детализация приносит лишь вред.

В следующей части (а их впереди еще три, и все уже давно написаны) будет рассмотрено буквальное и развернутое копирование - это не оно? А то терминов расплодилось немеряно Отлично

Я имею в виду то, что в литературе известно под названиями shallow copy и deep copy. Слабо представляю, что такое буквальное и развернутое копирование. Возможно, это на самом деле то же самое, просто издержки перевода терминов на русский язык. Доживем до следующей части - увидим.
Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 24-03-2005 16:32 » 

Буквальное копирование - это простое побитное копирование объекта. Оно означает, что количество и состояние всех битов одного объекта абсолютно точно воспроизводится во втором. Развернутое копирование делает все то же самое, что и буквальное, но плюс к этому обеспечивает еще и копирование ресурсов, связанных с членами класса - указателями. 
А литератур столько всяких... Видимо сколько и терминов Улыбаюсь
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Alf
Гость
« Ответ #4 : 24-03-2005 20:37 » 

А как "развернутое" и "буквальное" выглядели в оригинале в той литературе, откуда они родом?
Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 25-03-2005 03:35 » 

Откуда-то из той литературы, что в списке приведена, к сожалению, статьи писались в 2001г. и у меня уже и книжек-то тех нету. Но вот в "Бархатном пути", например есть даже термин "фотографическое" копирование...
Но то, что я это не сам придумал - факт.
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines