powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / что делает оператов присваивания в моем коде?
14 сообщений из 64, страница 3 из 3
что делает оператов присваивания в моем коде?
    #38099825
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, вы ж просили пример, когда не работает. Вот он:
Либо наоборот
Код: plaintext
1.
2.
3.
4.
	Person(const Person& from)
	{
		*this = from;
	}
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38099830
Т.е. тут
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
struct Person {
int a, b, c;
	Person(const Person& from)
	{
		a = from.a;    // 1. возможно?
		this->b = from.b; // 2.  возможно?
		*this = from; // 3. возможно?
	}
};


Anatoly Moskovskyвсе возможно в некоторых частных случаях.
а тут уже
Anatoly Moskovskyне работает:
Либо наоборот
Код: plaintext
1.
2.
3.
4.
	Person(const Person& from)
	{
		*this = from;
	}




Anatoly MoskovskyПриведите примерпропущено...

Приведите пример когда это не будет работать?
Например, почленное копирование из константной ссылки непотокобезопасно, т.к. неатомарно.
Ну так та же самая проблема и в вашем примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	Person& operator=(const Person& from)
	{
		Person temp = from;
		swap(temp);
		return *this;
	}
	void swap(Person& other)
	{
	 	std::swap(Name, other.Name);
	}	
	
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38099833
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
та же самая проблема Т.е. тут все возможно в некоторых частных случаях а тут уже не работает

Пример, с *this = from - не работает для реального класса рассмотренного в данном топике, где есть поле Name. А с вашими int конечно будет работать. Но вы же не думаете что вам так всегда будет везти?
Ведь пока я вам не указал на необходимость инициализации полей перед вызовом присвоения, вы и не вспомнили об этом, хотя уверен, что знали. Т.е. в реальном проекте когда дело дошло бы до подобного кода, вполне вероятно вы бы тоже забыли.

та же самая проблема
Anatoly Moskovsky
Например, почленное копирование из константной ссылки непотокобезопасно, т.к. неатомарно.
Ну так та же самая проблема и в вашем примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	Person& operator=(const Person& from)
	{
		Person temp = from;
		swap(temp);
		return *this;
	}
	void swap(Person& other)
	{
	 	std::swap(Name, other.Name);
	}	
	


А где вы в этом примере видете почленное копирование из внешнего объекта?
Или вы предполагаете что я бы криво написал конструктор копирования, который здесь не приведен?
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100029
Anatoly Moskovskyта же самая проблема Т.е. тут все возможно в некоторых частных случаях а тут уже не работает

Пример, с *this = from - не работает для реального класса рассмотренного в данном топике, где есть поле Name. А с вашими int конечно будет работать. Но вы же не думаете что вам так всегда будет везти?
Ведь пока я вам не указал на необходимость инициализации полей перед вызовом присвоения, вы и не вспомнили об этом, хотя уверен, что знали. Т.е. в реальном проекте когда дело дошло бы до подобного кода, вполне вероятно вы бы тоже забыли.
Я же писал, поля инициализируются конструктором по умолчанию сами - помнить не надо. А у кого нет такого конструктора, там компилятор подскажет - тоже помнить не надо.

Anatoly Moskovskyта же самая проблемапропущено...

Ну так та же самая проблема и в вашем примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	Person& operator=(const Person& from)
	{
		Person temp = from;
		swap(temp);
		return *this;
	}
	void swap(Person& other)
	{
	 	std::swap(Name, other.Name);
	}	
	


А где вы в этом примере видете почленное копирование из внешнего объекта?
Или вы предполагаете что я бы криво написал конструктор копирования, который здесь не приведен?
Нет, это вы предполагаете, что я бы криво написал оператор присваивания, который у меня не приведен.
Вы просто читали очень не внимательно и подумали, что я оставлю operator= по умолчанию, по этому у вас и какие-то проблемы с Name, многопоточностью и т.д.
Либо наоборот
Код: plaintext
1.
2.
3.
4.
	Person(const Person& from)
	{
		*this = from;
	}


Останется реализовать только оператор = с глубоким копированием . При изменении класса придется менять только его.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100045
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
читали очень не внимательноAnatoly Moskovskyпропущено...

Пример, с *this = from - не работает для реального класса рассмотренного в данном топике, где есть поле Name. А с вашими int конечно будет работать. Но вы же не думаете что вам так всегда будет везти?
Ведь пока я вам не указал на необходимость инициализации полей перед вызовом присвоения, вы и не вспомнили об этом, хотя уверен, что знали. Т.е. в реальном проекте когда дело дошло бы до подобного кода, вполне вероятно вы бы тоже забыли.
Я же писал, поля инициализируются конструктором по умолчанию сами - помнить не надо. А у кого нет такого конструктора, там компилятор подскажет - тоже помнить не надо.

Поле Name это указатель. У него нет и не может быть никаких конструкторов.
При входе в конструктор копирования там мусор, который в вашем операторе присвоения будет рассматриваться как адрес блока памяти который нужно освободить перед установкой нового значения.
И никакие известные мне компиляторы ничего не подсказывают в такой ситуации - такой анализ замедлил бы компиляцию, так как предполагает поиск пути в графах.

Таким образом, перед вызовом присвоения в к-торе копирования все равно нужно проинициализировать корректно каждое поле, и никакого преимущества в минимизации дублирования перенос логики копирования в оператор= не дает. Зато сложность кода растет, т.к. теперь конструктор и оператор зависят друг от друга.
В случае же когда логика находится в к-торе + swap, то только оператор= зависит от к-тора, а метод swap тривиален (он вообще в большинстве случаев может быть реализован как побитный swap всего объекта, без перечисления отдельных полей, а в остальных случаях - просто линейный регулярный код)
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100049
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
читали очень не внимательноНет, это вы предполагаете, что я бы криво написал оператор присваивания, который у меня не приведен.
Вы просто читали очень не внимательно и подумали, что я оставлю operator= по умолчанию, по этому у вас и какие-то проблемы с Name, многопоточностью и т.д.

Причем здесь корректность оператора=?
Я вам указал на проблему в конкретном коде конструктора, где перед вызовом = копируете два поля из from.
Это неатомарное действие, чья неатомарность не зависит от корректности кода =.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100090
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот тут обсуждаются эти два подхода и их достоинства и недостатки:
http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
http://stackoverflow.com/questions/3652103/implementing-the-copy-constructor-in-terms-of-operator

Краткое резюме: никаких достоинств у подхода реализующего конструктор копирования через оператор= нет. Зато недостатков полно.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100116
Anatoly Moskovskyчитали очень не внимательнопропущено...

Я же писал, поля инициализируются конструктором по умолчанию сами - помнить не надо. А у кого нет такого конструктора, там компилятор подскажет - тоже помнить не надо.

Поле Name это указатель. У него нет и не может быть никаких конструкторов.
При входе в конструктор копирования там мусор, который в вашем операторе присвоения будет рассматриваться как адрес блока памяти который нужно освободить перед установкой нового значения.
И никакие известные мне компиляторы ничего не подсказывают в такой ситуации - такой анализ замедлил бы компиляцию, так как предполагает поиск пути в графах.

Таким образом, перед вызовом присвоения в к-торе копирования все равно нужно проинициализировать корректно каждое поле, и никакого преимущества в минимизации дублирования перенос логики копирования в оператор= не дает. Зато сложность кода растет, т.к. теперь конструктор и оператор зависят друг от друга.
В случае же когда логика находится в к-торе + swap, то только оператор= зависит от к-тора, а метод swap тривиален (он вообще в большинстве случаев может быть реализован как побитный swap всего объекта, без перечисления отдельных полей, а в остальных случаях - просто линейный регулярный код)
Теперь понятно что вы имели ввиду.
Да, в случае динамического выделения памяти никакой пользы от моего подхода не будет. Естественно нужно будет указатели инициализировать NULL.
Но в любом случае в operator= делается проверка на NULL перед освобождением памяти и только затем выделение.
Хотя, не знаете, по стандарту указатели по умолчанию не инициализируются NULL/null_ptr?

Но если это не жизненно необходимо, лучше использовать умные указатели и контейнеры вместо обычных указателей для динамической памяти.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100120
Anatoly Moskovskyчитали очень не внимательноНет, это вы предполагаете, что я бы криво написал оператор присваивания, который у меня не приведен.
Вы просто читали очень не внимательно и подумали, что я оставлю operator= по умолчанию, по этому у вас и какие-то проблемы с Name, многопоточностью и т.д.

Причем здесь корректность оператора=?
Я вам указал на проблему в конкретном коде конструктора, где перед вызовом = копируете два поля из from.
Это неатомарное действие, чья неатомарность не зависит от корректности кода =.
Я привел примеры почленного копирования в конструкторе только, чтобы понять что вы имели ввиду.
Естественно предполагалось, что вариант operator= потокобезопасный.
Сейчас почитаю что там на stackoverflow пишут.

Кстати, std::swap по стандарту атомарный?
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100148
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
умные указатели и контейнерыХотя, не знаете, по стандарту указатели по умолчанию не инициализируются NULL/null_ptr?
По умолчанию не инициализируются, как и другие POD-члены без конструкторов.
Хотя в некоторых случаях (например когда у контейнера вообще нет пользовательских конструкторов) неявная инициализация членов нулями производится при явной инициализации контейнера через к-тор по умолчанию (T t = T()). Но к конструктору копирования это не относится.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100153
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
operator= потокобезопасныйКстати, std::swap по стандарту атомарный?
Нет. Но это обычно и не требуется.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100503
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GТогда я запутался, лучше делать проверку, или нет? :)
Разве что ассертом, так будет лучше всего. Потому что
Anatoly MoskovskyНо присвоение в себя - это ошибка кодирования.
В норме ее не должно быть.
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100605
static_assert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MozokMaximuS_GТогда я запутался, лучше делать проверку, или нет? :)
Разве что ассертом, так будет лучше всего. Потому что
Anatoly MoskovskyНо присвоение в себя - это ошибка кодирования.
В норме ее не должно быть.

А static_assert'ом это можно как-то отловить?
...
Рейтинг: 0 / 0
что делает оператов присваивания в моем коде?
    #38100617
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При компиляции нельзя определить.

Но я вообще думаю, что это не такая серьезная ошибка, чтобы ее наказывать ассертом.
И иногда при несильно продуманной архитектуре (а это почти любая архитектура ) такие ситуации неизбежны
Думаю падение скорости достаточное наказание :)
...
Рейтинг: 0 / 0
14 сообщений из 64, страница 3 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / что делает оператов присваивания в моем коде?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]