Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
4 / 1 / 0
Регистрация: 09.10.2015
Сообщений: 204
1

Нужно ли реализовать также отдельно конструктор копирования, если имеется перегруженный оператор присваивания?

17.09.2016, 16:30. Просмотров 1777. Ответов 18
Метки нет (Все метки)

у меня есть класс. и прототип перегруженной операции присваивания
C++
1
some_class& some_class::operator=(const some_class& some_object);
1)Нужно ли реализовать также отдельно конструктор копирования или достаточно только оператор перегрузить
2)я правильно,пониманию шаги при реализации перегрузки оператора?
--очистить память
-- переписать элементы
или есть еще что-то?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.09.2016, 16:30
Ответы с готовыми решениями:

Очередь, конструктор копирования и перегруженный оператор присваивания
#include <iostream> using namespace std; typedef char type; struct Node { type element;...

Конструктор копий и перегруженный оператор копирования
Привет! Изучил конструктор копий и перегруженный оператор копирования. Но не могу понять зачем в...

Конструктор копирования и оператор присваивания
Есть класс (синтетический, создан для примера) class Object { private: int a; float...

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

18
nd2
3399 / 2781 / 1250
Регистрация: 29.01.2016
Сообщений: 9,423
17.09.2016, 16:35 2
Лучший ответ Сообщение было отмечено Kristina_S как решение

Решение

Цитата Сообщение от Kristina_S Посмотреть сообщение
1)Нужно ли реализовать также отдельно конструктор копирования или достаточно только оператор перегрузить
Распространенные ошибки

Добавлено через 1 минуту
Цитата Сообщение от Kristina_S Посмотреть сообщение
--очистить память
После этого выделить новую.
1
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 16:40 3
1) Конечно, надо реализовать конструктор копирования!
Потому что есть запись
C++
1
myObj = myObj2;
, где надо перегружать присваивание,
А есть запись
C++
1
class myObj( myObj2 );
где необходимо реализовать отдельный конструктор копирования!
Абсолютно разные вещи!

2) Значит так:
Очищать память не всегда обязательно.
Если вы не используете указатели, то можно просто сразу скопировать в поля класса новую инфу без отдельного затирания.
Когда необходимо затирать?
Когда вы выделяете память скажем, для массива при помощи указателей. А массив может иметь разный объем элементов.
Или когда вы используете указатели, и может произойти ситуация, когда указатель станет указывать в никуда, и станет блуждающим ( а значит, может быть прострел памяти)
Вот тогда надо освобождать память от старых значений и подготавливать объект к копированию новой инфы.
тогда будет так:
- очистить память
- выделить новую
- копировать
0
4 / 1 / 0
Регистрация: 09.10.2015
Сообщений: 204
17.09.2016, 16:41  [ТС] 4
то есть,как я понял нужно и конструктор копирования реализовывать?
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 16:48 5
Цитата Сообщение от Kristina_S Посмотреть сообщение
то есть,как я понял нужно и конструктор копирования реализовывать?
И можно и нужно и хорошо так делать. потому что конструктор копирования и перегрузка присваивания - вещи похожие, но совершенно не одно и то же!
0
nd2
3399 / 2781 / 1250
Регистрация: 29.01.2016
Сообщений: 9,423
17.09.2016, 16:49 6
Цитата Сообщение от gledor Посмотреть сообщение
, где надо
А может и не надо, есть не явный.
Цитата Сообщение от gledor Посмотреть сообщение
где необходимо
А может и не необходимо, есть не явный.
Всё от класса зависит. Но, если есть необходимость, то тогда - "правило трёх".
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 16:55 7
Цитата Сообщение от nd2 Посмотреть сообщение
А может и не необходимо, есть не явный.
Конструктор копирования по умолчанию - есть самый неэффективный.
А еще он не работает с указателями. Если у вас будут в классах использованы указатели, а конструктор копирования неявный - это конкретный залёт. Это отстреливание обоих ног вместе с тестикулами. А так же появление множества нерегулярных, непонятных багов и эффектов вплоть до краха операционной системы. Даже если явный конструктор копирования реально не нужен, его лучше объявить - это правило хорошего тона. Показать все явное и неявное, чтобы не было чего-то недопонято.

Так что надо, Федя! Надо!
0
nd2
3399 / 2781 / 1250
Регистрация: 29.01.2016
Сообщений: 9,423
17.09.2016, 17:04 8
Цитата Сообщение от gledor Посмотреть сообщение
Если у вас будут в классах использованы указатели
Читать умеешь?
Цитата Сообщение от nd2 Посмотреть сообщение
Всё от класса зависит.
Ты ясновидящий? Видишь класс ТС?

Добавлено через 2 минуты
Цитата Сообщение от gledor Посмотреть сообщение
его лучше объявить - это правило хорошего тона
Тогда не пиши, что надо объявить.
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 17:13 9
Цитата Сообщение от nd2 Посмотреть сообщение
Читать умеешь?
Прекрасно умею. И все равно считаю, что надо в любом случае, пусть хоть небо обрушится.

1. И вообще. Помимо конструктора обязательно указывать void func( void ), если функция ничего не принимает.

2. пустой return; - если функция ничего не возвращает.

3. объявлять и инициализировать нулем переменую даже если вы присваиваете ей значение в следующей строке.

4. объявлять явно все три конструктора даже если вы не нуждаетесь в каком то из них.

5. Ставить { } - фигурные скобки даже если вы можете без них обойтись, например:
if( var )
cout << var;

лучше написать
if( var )
{
cout << var;
}
else
{
;
}

6. Ставить else после любого if, даже если оно не нужно. В таком случае ставить NOOP.

7. Ставить default: в любом case, даже если очевидно, что в нем нет необходимости. В таком случае ставить NOOP или возможное сообщение об ошибке.

8. И много много много другого.

Не нужен конструктор? Все равно делайте. Пусть и пустой.
Вопросы еще есть ко мне?))
0
nd2
3399 / 2781 / 1250
Регистрация: 29.01.2016
Сообщений: 9,423
17.09.2016, 17:15 10
Цитата Сообщение от gledor Посмотреть сообщение
Вопросы еще есть ко мне?))
И не было. Для меня, с тобой всё понятно.
0
Эксперт С++
3206 / 1733 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.09.2016, 17:36 11
gledor, вы что-то намешали очень умные правила с не очень умными.
С правилами 1, 2 и 6 категорически не согласен.
И очень интересно, вот
Цитата Сообщение от gledor Посмотреть сообщение
6. Ставить else после любого if, даже если оно не нужно. В таком случае ставить NOOP.
это вы сами придумали или вычитали где-то? Если вычитали, то можете источник указать?
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 18:46 12
№ 6 - С. Макконелл, Глава 15. Врезка "достоверные данные" под названием "Рассмотрите вопрос об использовании блока else" обычно на 349 странице русского издания. Сам автор считает свои слова небольшим преувеличением и советует писать хотя бы объяснение, почему нет else. Но это не выдуманные мной слова.

Это что касается номера 6.

номер 1 и 2 - вывод из главы 32 той же книги "Самодокументирующийся код".
Использование void при отсутствии параметров функции и пустого return; void - несомненно повышает ясность и очевидность кода, а так же помогает акцентировать внимание на ключевой детали работы метода или функции.
пустой return так же помогает повысить ясность кода и привлечь внимание к явному окончанию метода или функции и справляется с этим лучше, чем невзрачный }.
Сам автор ратует за улучшение восприятия кода и грамотное его форматирование. Во многих местах книги сквозит одна и та же мысль: "Лучше объявить или указать что-либо явно, чем не объявлять и не указывать явно, так как это является хорошей почвой для возникновения двойного смысла". Это относится так же и к применению скобок в выражениях навроде 2 + 2 *2 ( и о чем было не раз написано ). И к указанию типа signed long int вместо int ( о чем тоже упоминалось не раз ) и о предпочтении void и пустых return к их отсутствию.
0
Эксперт С++
3206 / 1733 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.09.2016, 21:14 13
Цитата Сообщение от gledor Посмотреть сообщение
№ 6 - С. Макконелл, Глава 15
Блин! Я вот всегда подозревал, что Макконнелл неспроста такой толстый!
Я читал его не подряд, да и не верю, что это возможно. Честно говоря, правило с пустым else меня поразило, он таки точно шизя, хотя и очень умная.
Вывод. Нельзя читать толстые книги подряд и полностью!
А правила 1 и 2 вы, получается, таки сами выдумали! Это еще один аргумент, чтобы не программировать на Си. Иногда последствия могут быть очень тяжелыми!
Не программируй, деточка, на Си, Макконнеллом снанешь!
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 21:22 14
Цитата Сообщение от Mr.X Посмотреть сообщение
А правила 1 и 2 вы, получается, таки сами выдумали! Это еще один аргумент, чтобы не программировать на Си. Иногда последствия могут быть очень тяжелыми!
А в чем тяжесть последствий?

Цитата Сообщение от Mr.X Посмотреть сообщение
Не программируй, деточка, на Си, Макконнеллом снанешь!
Мне наверняка стоит прислушаться к Вам!

Но пока мне не совсем понятно, чем void и пустой return; не только не хорошо но и плохо. Хотелось бы выслушать вашу точку зрения.
0
Эксперт С++
3206 / 1733 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.09.2016, 22:11 15
Цитата Сообщение от gledor Посмотреть сообщение
Мне наверняка стоит прислушаться к Вам!
Да-да, особенно к фразе
Цитата Сообщение от Mr.X Посмотреть сообщение
он таки точно шизя, хотя и очень умная.


Цитата Сообщение от gledor Посмотреть сообщение
Но пока мне не совсем понятно, чем void и пустой return; не только не хорошо но и плохо. Хотелось бы выслушать вашу точку зрения.
Ну, void это типично сишная фишка, и в плюсах не применяется.
Если функция ничего не возвращает, то это не что иное, как процедура в паскалевском смысле, т.е. ее смысл именно в том что она делает, т.е. в ее побочных эффектах. Процедура и функция - это принципиально разные вещи, и тот кто мостит return в процедуру, дает читателям понять, что он этого пока не осознал.

P.S. Я вот несколько колебался, когда добавлял "Fork you!" в свою подпись после цитаты из Макконнелла, а сейчас понимаю, что интуиция меня не подвела!
0
Миниатюры
Нужно ли реализовать также отдельно конструктор копирования, если имеется перегруженный оператор присваивания?  
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 22:19 16
Цитата Сообщение от Mr.X Посмотреть сообщение
Если функция ничего не возвращает, то это не что иное, как процедура в паскалевском смысле, т.е. ее смысл именно в том что она делает, т.е. в ее побочных эффектах. Процедура и функция - это принципиально разные вещи, и тот кто мостит return в процедуру, дает читателям понять, что он этого пока не осознал.
Если писать return; и представлять, что это возврат "пустоты" из процедуры - то я согласен, что это выглядит глупо.
0
13533 / 7187 / 1722
Регистрация: 30.01.2014
Сообщений: 12,019
17.09.2016, 22:23 17
Цитата Сообщение от gledor Посмотреть сообщение
чем void и пустой return; не только не хорошо но и плохо.
Это не плохо. Это просто бессмысленно.
Ну, вроде как писать комментарии напротив конструктора: "// это конструктор".
Человек, пишущий на С++ и так все поймет.
Что касается конкретно void в параметре, то в С это имело смысл. Потому как функции
C++
1
void foo();
и
C++
1
void foo(void);
- это разные функции. Первая, принимает потенциально любое количество аргументов, а вторая не принимает ничего. В С++ это не так, т.е. именно первая ничего не принимает, а вторая обозначает тоже самое и поддерживается исходя из соображений совместимости с кодом на Си, который может быть использован в С++ программах.

Поэтому конкретно эти два "правила" есть не что иное, как борьба с ветряными мельницами. В реальной практике ни у кого не возникает проблем с этими двумя вещами.
0
130 / 25 / 12
Регистрация: 12.08.2015
Сообщений: 213
17.09.2016, 22:30 18
Цитата Сообщение от DrOffset Посмотреть сообщение
Поэтому конкретно эти два "правила" есть не что иное, как борьба с ветряными мельницами. В реальной практике ни у кого не возникает проблем с этими двумя вещами.
Видимо да.

Ну, значит, эти два пункта - это мой ритуал, который я делаю ради своего душевного равновесия)))
0
С чаем беда...
Эксперт CЭксперт С++
7916 / 3833 / 1053
Регистрация: 18.10.2014
Сообщений: 8,158
17.09.2016, 22:32 19
Цитата Сообщение от Kristina_S Посмотреть сообщение
Нужно ли реализовать также отдельно конструктор копирования или достаточно только оператор перегрузить
Нужно. Более того, одной из популярных идиом для реализации копирующего оператора присваивания является copy-and-swap idiom, т.е. реализация оператора присваивания именно через конструктор копирования. Т.е.

C++
1
2
3
4
5
6
7
8
9
10
some_class::some_class(const some_class &rhs)
{
   // Копирование
}
 
some_class& some_class::operator=(some_class some_object)
{ // Параметр принимается по значению (!)
   swap(*this, some_object);
   return *this;
}
У такого варианта много преимуществ, в том числе избегание дублирование копирующего кода, который в таком варианте пишется только в конструкторе копирования. Для этого, правда, придется дополнительно реализовать функциональность swap для вашего класса.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.09.2016, 22:32

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Оператор присваивания через конструктор копирования
Возник такой вопрос. Как перегрузить оператор присваивания для класса через конструктор...

Про конструктор копирования, оператор присваивания
Объясните, пожалуйста, принцип действия конструктора копирования и операции присваивания. На что...

Конструктор копирования и оператор присваивания - общая часть, выделять ли в отдельный метод
Как лучше? // конструктор копирования Fraction::Fraction( const Fraction&amp; rhs ) { //...

Ребят, уже запарился, гляньте, что не так!? конструктор копирования и оператор присваивания
#include &lt;iostream&gt; using namespace std; struct SNode { SNode*next; int val; ...

Перегруженный оператор присваивания
Достаточно информации прочитал, что такое перегруж. оператор присваивания, но не до конца понимаю...

Перегруженный оператор присваивания
Добрый вечер! Встретил пример в книге, где есть перегруженный оператор присваивания. В итоге код...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.