powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / переопределенный оператор - возвращение типа по ссылке и по значению
25 сообщений из 32, страница 1 из 2
переопределенный оператор - возвращение типа по ссылке и по значению
    #38107961
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
У меня есть класс Example с перегруженным оператором присваивания:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
class Example
{
public:
	int eField1;
	
	Example(int value)
	{
		eField1 = value;
	}
	
	Example()
	{
	}
	
	Example& operator+(const Example &from)
	{
		Example temp;
		temp.eField1 = this->eField1+from.eField1;
		return temp;
	}
};

int main()
{
	Example obj, obj1(2),obj2(3);
	obj = obj1+obj2;
	return 0;
}


В данной реализации
Код: plaintext
1.
Example& operator+(const Example &from)


возвращается ссылка на объект, но я могу без проблем вернуть и сам объект
Код: plaintext
1.
Example operator+(const Example &from)


У меня соответственно вопрос какая разница возвращать объект по значению или по ссылке? И как правильно?
Заранее спасибо!
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38107962
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторУ меня есть класс Example с перегруженным оператором сложения:
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38107972
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GУ меня соответственно вопрос какая разница возвращать объект по значению или по ссылке? И как правильно?

Ссылку - неправильно, т.к. при выходе из оператора объект, на которрый она ссылается будет уничтожен, и она станет невалидной.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38107991
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMaximuS_GУ меня соответственно вопрос какая разница возвращать объект по значению или по ссылке? И как правильно?

Ссылку - неправильно, т.к. при выходе из оператора объект, на которрый она ссылается будет уничтожен, и она станет невалидной.
Спасибо за комментарий! Не очень понятно, что значит "при выходе из оператора". При выходе из функции "operator+"?
А если тогда рассматривать кейс без нового объекта:
Код: plaintext
1.
2.
3.
4.
5.
	Example& operator+(const Example &from)
	{
		this->eField1 = this->eField1+from.eField1;
		return *this;
	}
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108021
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Нет, возвращать надо именно новый объект, иначе вы производите операцию =+, а не +.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108068
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMaximuS_G,

Нет, возвращать надо именно новый объект, иначе вы производите операцию =+, а не +.
Еще больше запутался. Давайте тогда по порядку. Можете, подробно обяснить, что Вы имели ввиду здесь?
Ссылку - неправильно, т.к. при выходе из оператора объект, на которрый она ссылается будет уничтожен, и она станет невалидной.
Ведь такой код нормально работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
int main()
{
	Example obj, obj1(2),obj2(3);
	obj = obj1+obj2;
	cout<<obj.eField1;
	return 0;
}


То есть ссылка нормально передалась, я так понимаю.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108074
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Повезло просто, что участок памяти в котором был объект еще не занят другим объектом.

Вы верите, что вам и дальше будет везти?
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108113
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть класс Example с перегруженным оператором присваивания:


Тут нет перегруженного =

Код: plaintext
1.
Example& operator+(const Example &from)


возвращается ссылка на объект, но я могу без проблем вернуть и сам объект
Код: plaintext
1.
Example operator+(const Example &from)




Тут ты ОБЯЗАН вернуть объект по значению. По ссылке возвращать нельзя, ей просто не на что ссылаться.


Также этот оператор должен быть const.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108116
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GAnatoly MoskovskyMaximuS_G,

Нет, возвращать надо именно новый объект, иначе вы производите операцию =+, а не +.
Еще больше запутался. Давайте тогда по порядку. Можете, подробно обяснить, что Вы имели ввиду здесь?


Напиши себе подробно что должен делать твой оператор, какие действия, про шагам, на русском языке, и ты всё сам поймеш.
Если нет, сделай то же самое для operator += и сравни описания. Если опять нет - шли оба описания сюда.

MaximuS_GСсылку - неправильно, т.к. при выходе из оператора объект, на которрый она ссылается будет уничтожен, и она станут невалидной.
Ведь такой код нормально работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
int main()
{
	Example obj, obj1(2),obj2(3);
	obj = obj1+obj2;
	cout<<obj.eField1;
	return 0;
}


То есть ссылка нормально передалась, я так понимаю.

Ты понимаеш неправильно. Код НЕ работает, что он работает, тебе просто кажется.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108597
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivУ меня есть класс Example с перегруженным оператором присваивания:


Тут нет перегруженного =

Код: plaintext
1.
Example& operator+(const Example &from)


возвращается ссылка на объект, но я могу без проблем вернуть и сам объект
Код: plaintext
1.
Example operator+(const Example &from)




Тут ты ОБЯЗАН вернуть объект по значению. По ссылке возвращать нельзя, ей просто не на что ссылаться.


Также этот оператор должен быть const.
Спасибо за комментарий!
авторТакже этот оператор должен быть const.
Так?
авторExample& operator+(const Example &from) const
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108599
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMaximuS_G,

Повезло просто, что участок памяти в котором был объект еще не занят другим объектом.

Вы верите, что вам и дальше будет везти?
Я понял, спс) Попробовал все таки получить кривой результат, для этого объявил obj как ссылку, что бы объект не копировался, а просто по ссылке ссылался. Создал еще пару объектов после этого. Но память, на которую ссылка указывает, все равно не зачистилась.
Код: plaintext
1.
2.
3.
4.
5.
	Example obj1(2),obj2(3);
	Example& obj = obj1;
	obj = obj1+obj2;
	Example obj3(2),obj4(3);
	cout<<obj.eField1;


Есть верный способ, что бы память там затереть, и что бы тогда cout<<obj.eField1 вывел мусор?
Заранее спасибо!
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108610
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMaximuS_G,

Нет, возвращать надо именно новый объект, иначе вы производите операцию =+, а не +.
Ага, после раздумий кажется понял :). Вы имеете ввиду, что операция =+ производится здесь
авторobj = obj1+obj2 ;
То есть как будто просто в коде написать вот так:
Код: plaintext
1.
2.
3.
...
obj1+obj2;
...


?

Я попробовал перегрузить операцию "=+" - копмилятор говорит, что ошибка.
авторExample operator=+(const Example &from) const
Этот оператор перегрузить нельзя?

Заранее спасибо!
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108613
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GЕсть верный способ, что бы память там затереть, и что бы тогда cout<<obj.eField1 вывел мусор?

Самое простое - в деструкторе Example обнулять поле eField1.
И тогда ваш оператор всегда будет давать 0 в качестве результата.

На самом деле в деструкторах реальных объектов может происходить многое, после чего останками объекта ни в коем случае нельзя пользоваться. Так что до затирания памяти другими объектами не обязательно дойдет :)

Но и затирание тоже можно продемонстрировать.
Например водном выражении вычислите сумму 3-х слагаемых, а не 2-х.
Код: plaintext
1.
obj = obj1+obj2 + obj2;


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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	Example& operator+(const Example &from)
	{
		Example temp;
		temp.eField1 = 0;// здесь мы затираем место где мог находиться удаленный объект (в этом случае this == &temp)
		temp.eField1 = this->eField1+from.eField1;
		return temp;
	}
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108615
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GAnatoly MoskovskyMaximuS_G,

Нет, возвращать надо именно новый объект, иначе вы производите операцию =+, а не +.
Ага, после раздумий кажется понял :). Вы имеете ввиду, что операция =+ производится здесь
авторobj = obj1+obj2 ;
То есть как будто просто в коде написать вот так:
Код: plaintext
1.
2.
3.
...
obj1+obj2;
...


?

Я не понял что вы имеете в виду, но одно точно - вы все еще неверно понимаете как надо реализовывать операторы + и =+, и что они делают.

Я попробовал перегрузить операцию "=+" - копмилятор говорит, что ошибка.
авторExample operator=+(const Example &from) const
Этот оператор перегрузить нельзя?

Можно, но вот тут как раз надо убрать const и добавить ссылку в результат, т.к. =+ должен модифицировать объект и его же вернуть.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108618
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я что-то пропустил и в C/C++ появились "альтернативные" операторы с присваиванием?
А чем тогда "=+" отличается от "+="? Сначала присваивает, а потом складывает? А зачем?
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108624
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovЯ что-то пропустил и в C/C++ появились "альтернативные" операторы с присваиванием?
А чем тогда "=+" отличается от "+="? Сначала присваивает, а потом складывает? А зачем?
Это была опечатка :)
Правильный оператор +=.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108627
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GЯ попробовал перегрузить операцию "=+" - копмилятор говорит, что ошибка.
авторExample operator=+(const Example &from) const
Этот оператор перегрузить нельзя?такого оператора не существует, зато есть оператор +=, о котором и говорит Anatoly Moskovsky.
Код: plaintext
1.
Example & operator+=( const Example &rhs );
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108677
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так?

авторExample& operator+(const Example &from) const [/quot]

Нет.


Example operator+(const Example &from) const;
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108679
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть верный способ, что бы память там затереть, и что бы тогда cout<<obj.eField1 вывел мусор?
Заранее спасибо![/quot]

Да, собери приложение в релизной сборке с оптимизацией... Правда, чётких гарантий нет всё равно и не может быть.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108684
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G
Код: plaintext
1.
2.
3.
4.
5.
	Example obj1(2),obj2(3);
	Example& obj = obj1;
	obj = obj1+obj2;
	Example obj3(2),obj4(3);
	cout<<obj.eField1;


Есть верный способ, что бы память там затереть, и что бы тогда cout<<obj.eField1 вывел мусор?
Заранее спасибо!

Во, придумал, попробуй создать несколько автоматических объектов или переменных после вызова operator+ и получения его результата, а потом попробуй прочитать результат. Что должно произойти -- переменные должны перетереть память, ранее занимаемую этм объектом, и ты должен увидеть вместо результата какой-то мусор.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	Example a(2),b(3);
	Example& res =  a + b; // should be 5
	Example c(42);
	Example c2(42);
	Example c3(42);
	Example c4(42);
        int buf[1024];
        memset( buf, 42, sizeof(int) * 1024 );
        std::cout << "value of result (should be 5) :" << res << std::endl;
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108685
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G
Я попробовал перегрузить операцию "=+" - копмилятор говорит, что ошибка.
авторExample operator=+(const Example &from) const
Этот оператор перегрузить нельзя?



Потому что операция нифига не "=+", а "+=".
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38108877
teo609
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если код из поста 1 скормить студии 2010, то получаем warning C4172, вот справка о нем:

MSDNCompiler Warning (level 1) C4172 Visual Studio 2010
returning address of local variable or temporary

A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns , so the address returned is not valid.

Redesign the function so that it does not return the address of a local object.

The following sample generates C4172:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
// C4172.cpp
// compile with: /W1 /LD
float f = 10;

const double& bar() {
// try the following line instead
// const float& bar() {
   return f;   // C4172
}




Локальные и временные объекты разрушаются после выхода из функции, но до присваивания возвращаемого значения чему-то другому.
В простых случаях ничто не затирает память, занятую временными и локальными объектами.
Чтобы присваивание не сработало, нужно, чтобы эта память использовалась чем-то еще.
Это может быть не только деструктор возвращаемого по ссылке объекта,
но и оператор, выполняющий присваивание временного объекта, если перед собственно присваиванием он использует память этого временного объекта, например, под свои локальные объекты.
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38109146
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо большое за ответы!
Anatoly MoskovskyЭто была опечатка :)
Правильный оператор +=.
Да, действительно такой оператор получается переопределить.
А странно тогда, почему в main() прокатывают оба оператора:
Код: plaintext
1.
2.
3.
4.
int t = 3;
t =+ 2;
t += 2;
cout<<t; // 7


Компилятор сам заменяет неправильный оператор на правильный?
Anatoly MoskovskyЯ не понял что вы имеете в виду, но одно точно - вы все еще неверно понимаете как надо реализовывать операторы + и =+, и что они делают.
Как я понимаю :). У оператора "+" два операнда. Но можно и один сделать.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	void operator+()
	{
		this->eField1 += 1;
	}
int main()
{
	Example obj;
	+obj; // вот такая операция
}


Или для изменения объекта без последующего присваивания лучше переопределять операцию "++", а оператор "+" использовать для двух операндов (и последующего присвоения результата операции)?

И у меня тогда остается такой вопрос, нужно ли возвращать ссылку на себя, если изменяется объект, но измененный объект ничему не присваивается?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	void operator+() // или Example& operator+() ???
	{
		this->eField1 += 1;
		// или *this ???
	}
int main()
{
	Example obj;
	+obj; // вот такая операция
}
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38109256
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
teo609 , не очень понятно, что здесь происходит. Сможете прояснить немного?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
// C4172.cpp
// compile with: /W1 /LD
float f = 10;

const double& bar() {
// try the following line instead
// const float& bar() {
   return f;   // C4172
}
...
Рейтинг: 0 / 0
переопределенный оператор - возвращение типа по ссылке и по значению
    #38109833
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GА странно тогда, почему в main() прокатывают оба оператора:
Код: plaintext
1.
2.
3.
int t = 3;
t =+ 2;
t += 2;

Потому, что синтаксис надо учить.
Во второй строке переменной t, имевшей значение 3, переприсваивается значение 2. С явным указанием необязательного знака плюс.
В третьей строке выполняется оператор с присваиванием и в результате получается 4.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / переопределенный оператор - возвращение типа по ссылке и по значению
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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