FeelUs
|
|
« : 20-03-2011 13:42 » |
|
я хочу возвращать объект из функции по значению (не по ссылке) и прсваивать то, что вернула ф-ция, в другой объект.
при возврате из ф-ции создается (с помощью копиКонструктора) промежуточный объект, потом ф-ция завершается (со всеми деструкторами локальных объектов и т.п.)
и оператор присваивания у меня должен брать объект по ссылке (т.к. его надо менять) а этот промежуточный объект нельзя передавать по ссылке в оператор присваивания (пишет не может найти оператор присваивания, куда передается не по ссылке) тоже самое с копи конструктором (однако в другую ф-цию (не оператор присваивания) этот объект по ссылке передается нормально - почему?) (делать 2 перегруженных оператора присваивания в которые в один передается по ссылке, а в другой по значению нельзя, т.к. компилятору не положено в общем случае догадываться где какой использовать, да это в общем-то и не работает)
я пока нашел такое решение: взять адрес от этого промежуточного объекта, а потом его разыменовать - работает
вопрос: могу ли я быть уверен, что у этого промежуточного объекта деструктор не вызовется до того как я его передам в оператор присваивания таким образом? что значит взять адрес от него, и где он находится? можно ли решить данную проблему как-то более просто?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 20-03-2011 14:26 » |
|
Думаю, дело в несоответствии твоего конструктора копирования спецификации. Вероятно у тебя аргумент не const. myclass(myclass &arg); // не верно
myclass(const myclass &arg); // верно Добавлено через 7 минут и 57 секунд:Только не надо путать присваивание и копирование! Это разные операции. Добавлено через 4 минуты и 19 секунд:#include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { printf("Destructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(int x = 0) : x(x) { printf("Constructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(const myclass &s) : x(s.x) { printf("Copy by ref (0x%08x)\n", (unsigned int)(void*)this); }
myclass& operator=(const myclass &s) { assert(&s != this);
x = s.x; printf("Assign by ref (0x%08x)\n", (unsigned int)(void*)this); return *this; }
void print() { printf("Value (0x%08x): %d\n", (unsigned int)(void*)this, x); } };
myclass func() { myclass b(2);
return b; }
int main() { myclass b(1); myclass a = b; // инициализация - используется конструктор копирования. a.print();
a = func(); // присваивание - используется operator=. a.print();
return 0; } Constructor (0xbfc40588) Copy by ref (0xbfc40584) Value (0xbfc40584): 1 Constructor (0xbfc4058c) Assign by ref (0xbfc40584) Destructor (0xbfc4058c) Value (0xbfc40584): 2 Destructor (0xbfc40584) Destructor (0xbfc40588)
Добавлено через 2 минуты и 23 секунды:Рекомендую статьи: 1. Копирование и присваивание https://club.shelek.ru/viewart.php?id=243https://club.shelek.ru/viewart.php?id=244https://club.shelek.ru/viewart.php?id=247https://club.shelek.ru/viewart.php?id=258https://club.shelek.ru/viewart.php?id=2592. Оператор operator= https://club.shelek.ru/viewart.php?id=260https://club.shelek.ru/viewart.php?id=261
|
|
« Последнее редактирование: 20-03-2011 14:41 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
FeelUs
|
|
« Ответ #2 : 20-03-2011 16:13 » |
|
статьи пока еще не прочитал, но у меня в примерно в такомже классе и оператор присваивания и конструктор копирования не соответствуют спецификации (нет const), но все равно вызываются как встроенные и если поставить const то тоже ненадо никаких *& ставить между присваиванием и вызовом ф-ции но класс у меня олицетворяет указатель на дерево и при деструкторе оно должно удаляться =>если окажется 2 указателя на одно и тоже дерево получится не хорошо и при операторе приваивания у меня указатели просто меняются а при копиКонструкторе исходный указатель становится NULL =>у меня они не могут быть const вопрос остается в силе а мой c++ builder 6 выдал мне Constructor <0x0012ff88> Copy by ref <0x0012f f84> Value <0x0012ff84>: 1 Constructor <0x0012ff4c> Copy by ref <0x0012ff80> Destructor <0x0012ff4c> Assign by ref <0x0012ff84> Destructor <0x0012ff80> Value <0x0012ff84>: 2 Destructor <0x0012ff84> Destructor <0x0012ff88> Только не надо путать присваивание и копирование! Это разные операции. если вы имели ввиду оператор присваивания и конструктор копирования, то я вас понял
|
|
« Последнее редактирование: 20-03-2011 16:29 от FeelUs »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #3 : 20-03-2011 17:21 » |
|
FeelUs, огромная просьба: не торопись и выражай свои мысли яснее. И про правила языка не забывай.
Какой компилятор? Версия?
|
|
« Последнее редактирование: 20-03-2011 17:29 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
FeelUs
|
|
« Ответ #4 : 20-03-2011 18:23 » |
|
//--------------------------------------------------------------------------- #pragma hdrstop //---------------------------------------------------------------------------
#include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { printf("Destructor (0x%08x)", (unsigned int)(void*)this); fgetc(stdin); }
myclass(int x = 0) : x(x) { printf("Constructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(const myclass &s) : x(s.x) { printf("Copy by ref (0x%08x)\n", (unsigned int)(void*)this); }
myclass& operator=(const myclass &s) { assert(&s != this);
x = s.x; printf("Assign by ref (0x%08x)\n", (unsigned int)(void*)this); return *this; }
void print() { printf("Value (0x%08x): %d\n", (unsigned int)(void*)this, x); } };
myclass func() { myclass b(2);
return b; }
#pragma argsused int main() { myclass b(1); myclass a = b; // èíèöèàëèçàöèÿ - èñïîëüçóåòñÿ êîíñòðóêòîð êîïèðîâàíèÿ. a.print();
a = func(); // ïðèñâàèâàíèå - èñïîëüçóåòñÿ operator=. a.print();
return 0; } //--------------------------------------------------------------------------- выдает Constructor <0x0012ff88> Copy by ref <0x0012ff84> Value <0x0012ff84>: 1 Constructor <0x0012ff4c> Copy by ref <0x0012ff80> Destructor <0x0012ff4c> Assign by ref <0x0012ff84> Destructor <0x0012ff80> Value <0x0012ff84>: 2 Destructor <0x0012ff84> Destructor <0x0012ff88> //--------------------------------------------------------------------------- #pragma hdrstop //---------------------------------------------------------------------------
#include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { printf("Destructor (0x%08x)", (unsigned int)(void*)this); fgetc(stdin); }
myclass(int x = 0) : x(x) { printf("Constructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(myclass &s) : x(s.x) { printf("Copy by ref (0x%08x)\n", (unsigned int)(void*)this); }
myclass& operator=(myclass &s) { assert(&s != this);
x = s.x; printf("Assign by ref (0x%08x)\n", (unsigned int)(void*)this); return *this; }
void print() { printf("Value (0x%08x): %d\n", (unsigned int)(void*)this, x); } };
myclass func() { myclass b(2);
return b; }
#pragma argsused int main() { myclass b(1); myclass a = b; // èíèöèàëèçàöèÿ - èñïîëüçóåòñÿ êîíñòðóêòîð êîïèðîâàíèÿ. a.print();
a = *&func(); // ïðèñâàèâàíèå - èñïîëüçóåòñÿ operator=. a.print();
return 0; } //--------------------------------------------------------------------------- без *& пишет [C++ Error] Unit1.cpp(58): E2285 Could not find a match for 'myclass::operator =(myclass)' выдает Constructor <0x0012ff88> Copy by ref <0x0012ff84> Value <0x0012ff84>: 1 Constructor <0x0012ff4c> Copy by ref <0x0012ff80> Destructor <0x0012ff4c> Assign by ref <0x0012ff84> Destructor <0x0012ff80> Value <0x0012ff84>: 2 Destructor <0x0012ff84> Destructor <0x0012ff88> #pragma... - создается компилятором в самом начале, я оставляю русские крокозябры появляются только при копировании через буфер обмена ИЗ компилятора
|
|
« Последнее редактирование: 20-03-2011 18:33 от FeelUs »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 20-03-2011 18:34 » |
|
Борланд работает по какому-то своему стандарту. В настройках проекта можно переключить на ANSI, то тогда заголовки VCL не будут компилироваться.
FeelUs, нифига не понятно. Ты привел один и тот же код. Еще раз: пиши понятнее. Думаешь, охота ломать глаза и голову и искать, что же ты там сделал?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
FeelUs
|
|
« Ответ #6 : 20-03-2011 18:41 » |
|
второй код отличается от первого тем, что в в операторе присваивания и в конструкторе копирования отсутствует const если при использовании класса не добавить *& между присваиванием и вызовом ф-ции, пишет ошибку если добавить - работает #pragma мне кажется ни на что не влияет
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #7 : 21-03-2011 08:28 » |
|
Может кто-нибудь проверить на компиляторах MS?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #8 : 21-03-2011 08:35 » |
|
В какой студии? Имеется 2003 - 2010.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 21-03-2011 08:38 » |
|
Если не трудно, то в двух крайних Т.ч. точно быть уверенным, как MSVC работает. Жень, код бери из моего поста №1.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 21-03-2011 08:44 » |
|
Может кто-нибудь проверить на компиляторах MS?
а что проверить ? а так myclass( const myclass &s) myclass& operator=( const myclass &s) Добавлено через 46 секунд:в шестёрке нормально компилится, в остальных Джон проверит ))
|
|
« Последнее редактирование: 21-03-2011 08:45 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 21-03-2011 08:52 » |
|
Не, Леш, вот это: #include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { printf("Destructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(int x = 0) : x(x) { printf("Constructor (0x%08x)\n", (unsigned int)(void*)this); }
myclass(const myclass &s) : x(s.x) { printf("Copy by ref (0x%08x)\n", (unsigned int)(void*)this); }
myclass& operator=(const myclass &s) { assert(&s != this);
x = s.x; printf("Assign by ref (0x%08x)\n", (unsigned int)(void*)this); return *this; }
void print() { printf("Value (0x%08x): %d\n", (unsigned int)(void*)this, x); } };
myclass func() { myclass b(2);
return b; }
int main() { myclass b(1); myclass a = b; // инициализация - используется конструктор копирования. a.print();
a = func(); // присваивание - используется operator=. a.print();
return 0; } Нужно не только скомпилировать, но и выполнить, а результат сюда показать Добавлено через 40 секунд:BCB6 у меня показывает тоже самое, что у FeelUs получилось. Добавлено через 1 минуту и 23 секунды:Результат в первом посте получен на gcc 4.1.2.
|
|
« Последнее редактирование: 21-03-2011 08:55 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 21-03-2011 08:59 » |
|
VS6 Constructor (0x0012ff70) Copy by ref (0x0012ff6c) Value (0x0012ff6c): 1 Constructor (0x0012fef4) Copy by ref (0x0012ff68) Destructor (0x0012fef4) Assign by ref (0x0012ff6c) Destructor (0x0012ff68) Value (0x0012ff6c): 2 Destructor (0x0012ff6c) Destructor (0x0012ff70)
|
|
« Последнее редактирование: 21-03-2011 09:01 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #13 : 21-03-2011 09:05 » |
|
VS 2010 Ultimate Win32 C++ Console Project Constructor (0x002aff10) Copy by ref (0x002aff04) Value (0x002aff04): 1 Constructor (0x002afdf0) Copy by ref (0x002afe2c) Destructor (0x002afdf0) Assign by ref (0x002aff04) Destructor (0x002afe2c) Value (0x002aff04): 2 Destructor (0x002aff04) Destructor (0x002aff10) VS 2003 Version 7.1.3088 Constructor (0x0012fe90) Copy by ref (0x0012fe84) Value (0x0012fe84): 1 Constructor (0x0012fd74) Copy by ref (0x0012fdac) Destructor (0x0012fd74) Assign by ref (0x0012fe84) Destructor (0x0012fdac) Value (0x0012fe84): 2 Destructor (0x0012fe84) Destructor (0x0012fe90)
|
|
« Последнее редактирование: 21-03-2011 09:12 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #14 : 21-03-2011 11:07 » |
|
Спасибо Значит выходит, что gcc оптимизирует, а BCB и VC делает код с двойной работой.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
FeelUs
|
|
« Ответ #15 : 21-03-2011 16:30 » |
|
напомню и обобщу вопрос: есть некоторый класс, назавем его tree - состоит из одного указателя и кучи ф-ций , есть функция вида - в роли ее у меня выступает оператор присваивания и конструктор копирования и есть функция вида - в ней у меня создается дерево и надо сделать так , но возникает ошибка, но можно сделать могу ли я быть уверен, что деструктор промежуточного объекта не вызовется до того, как над ним поработает f()? Добавлено через 20 минут и 59 секунд:информация для тех, кто захочет предложить альтернативный вариант class TNode; class Tree { TNode *lp; public: Tree(Tree &x) { lp=x.lp; x.lp=NULL; } Tree &operator=(Tree &x) { TNode *p=x.lp; x.lp=lp; lp=p; } ~Tree() { //удаление всех узлов (конечно если lp!=NULL) lp=NULL; } //и куча других методов };
Tree CreateTree() { Tree x; //далее над x'ом удобнее работать как над локальной переменной return x; }
использование { Tree x;
x=*&CreateTree(); }
|
|
« Последнее редактирование: 21-03-2011 16:50 от FeelUs »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 21-03-2011 17:24 » |
|
могу ли я быть уверен, что деструктор промежуточного объекта не вызовется до того, как над ним поработает f()?
Можешь. Если в чем неуверен - читай документацию. И экспериментируй. Следующий тест: #include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { printf("0x%08x: destructor\n", (unsigned int)(void*)this); }
myclass(int x = 0) : x(x) { printf("0x%08x: constructor\n", (unsigned int)(void*)this); }
myclass(const myclass &s) : x(s.x) { printf("0x%08x: copy by ref\n", (unsigned int)(void*)this); }
myclass& operator=(const myclass &s) { assert(&s != this);
x = s.x; printf("0x%08x: assign by ref\n", (unsigned int)(void*)this); return *this; }
void print() { printf("0x%08x: value: %d\n", (unsigned int)(void*)this, x); } };
myclass func() { myclass b(2);
printf("0x%08x: func()\n", (unsigned int)(void*)&b); return b; }
void func2(myclass s) { printf("0x%08x: func2()\n", (unsigned int)(void*)&s); s.x = 3; }
int main() { myclass b(1); myclass a = b; a.print();
a = func(); a.print();
func2(func());
return 0; }
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
FeelUs
|
|
« Ответ #17 : 21-03-2011 18:01 » |
|
читай документацию она в большинстве случаев нерусская. а у меня с нерусским ооочень плохо я собственно и пишу универсальный парсер, чтобы с помощью него было легко и просто написать свой переводчик (которые существуют меня, видишь ли, не устраивают) экспериментируй эксперименты показывают, что второй закон Ньютона выполняется, а где гарантия, что он не изменится через пару минут а как по стандарту с++ должно быть?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 21-03-2011 18:18 » |
|
я собственно и пишу универсальный парсер, чтобы с помощью него было легко и просто написать свой переводчик английского ? )
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #19 : 21-03-2011 18:22 » |
|
Скомпилированный код не изменится точно.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #20 : 22-03-2011 07:48 » |
|
эксперименты показывают, что второй закон Ньютона выполняется, а где гарантия, что он не изменится через пару минут За последние примерно 300 лет ещё ни разу не изменился. Так что через пару минут не изменится. Гарантирую.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
FeelUs
|
|
« Ответ #21 : 16-04-2011 16:36 » |
|
За последние примерно 300 лет ещё ни разу не изменился. Так что через пару минут не изменится. Гарантирую. за 300 лет ни разу не изменился и как из этого следует что он не изменится через пару минут?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #22 : 17-04-2011 17:40 » |
|
Интуиция подсказывает, и стандарт подтверждает, что временные объекты должны удаляться только при достижении конца выражения Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. Там есть ещё исключения, но они работают в другую сторону (продления времени жизни временных объектов). Думаю, никто не может поручиться, что в один прекрасный момент какой-то компилятор почему-то не перестанет поддерживать стандарт (сам стандарт уже никуда деться не может, поскольку в силу работы над c++0x вряд ли кто-то станет делать новую правку в старом стандарте). Например, баги будут в компиляторе. Только страховаться от наступления такого события - значит, вообще не писать на языке сколько-нибудь сложных конструкций из-за риска, что они в каких-то условиях вдруг перестанут работать. Некоторые языки чуть не раз в год синтаксис меняют - и ничего, пишут на них люди. Так что метафора с вторым законом Ньютона здесь не подходит. Даже если завтра время жизни временной переменной в C++ может почему-либо измениться - это не основание не писать код так, как нужно сегодня. Всё равно при переходе на новый компилятор нужно будет код тестировать (можно заложить отдельный специальный тест, если боязно), ибо там наверняка навылезет каких-нибудь ещё граблей, связанных с вольным толкованием стандарта, и от этого уж точно нельзя подстраховаться. Ну, придётся пофиксить код, чтобы он там работал. Ну и что?
|
|
|
Записан
|
|
|
|
FeelUs
|
|
« Ответ #23 : 20-05-2011 04:43 » |
|
спасибо большое, Вад, что посмотрели стандарт, это нужно для того, чтобы знать на кого ругаться и материться, если что спасибо также, Вад, что рассказали текущую ситуацию в языках программирования... но именно это и должно нас подталкивать к поиску альтернативных вариантов , чтобы все было просто и красивоначнем с того, что есть переменные и есть значения (помоему это называется l-value и r-value)(что это (значения) - для элементарных переменных - понимаем, для классов - сейчас выясним) и константные ссылки можно инициализировать и константными переменными (получается ссылка на эту переменную) и значениями (тоже получается ссылка на хз какую переменную, инициализированную копи конструктором) ) а также есть const_cast<>(), который снимает константность таким образом такой код работает ... Tree(const Tree &x) { lp=x.lp; const_cast<Tree &>(x).lp=NULL; } Tree &operator=(Tree &x) { TNode *p=x.lp; const_cast<Tree &>(x).lp=lp; lp=p; } ... правда теперь нельзя создавать константные деревья, но если они мне понадобятся - напишу отдельный класс взаимодействующий с этим и если мы таким образом меняем константную ссылку (ссылающуюся на нек. переменную, даже если она константная), то интуиция и опыты подсказывают, что эта переменная и будет меняться "значение" объекта, помоему, можно получить только при возвращении объекта из функции по значению но получается, что это необычное "значение" у него даже адрес можно получить & также наблюдается интересный эффект при инициализации константной ссылки или просто переменной класса результатом функции копи конструктор от пром. объекта не вызывается, а ссылка (или эта переменная) начинает на него ссылаться опыты проводились над: //--------------------------------------------------------------------------- #pragma hdrstop //---------------------------------------------------------------------------
#include <stdio.h> #include <assert.h>
class myclass { public: int x;
~myclass() { print("Destructor "); fgetc(stdin); }
myclass(int x = 0) : x(x) { print("Constructor "); }
myclass(myclass &s) : x(s.x) { const_cast<myclass &>(s).x=0; print("Copy constructor "); s.print(" from "); }
myclass& operator=(myclass const &s) { assert(&s != this);
x = s.x; const_cast<myclass &>(s).x=0; print("operator= "); s.print(" from "); return *this; }
void print(char *str="")const { printf("%sValue (0x%08x): %d\n", str, (unsigned int)(void*)this, x); } };
myclass func() { printf("IN FUNCTION first\n"); myclass b(2);
printf("IN FUNCTION before return\n"); return b; }
#pragma argsused int main() { myclass b(1); myclass a = b; // èíèöèàëèçàöèÿ - èñïîëüçóåòñÿ êîíñòðóêòîð êîïèðîâàíèÿ. a.print();
myclass c = func(); //myclass &c = func(); printf("AFTER OPERATOR=\n"); c.print();
a = func(); // ïðèñâàèâàíèå - èñïîëüçóåòñÿ operator=. printf("AFTER OPERATOR=\n");
return 0; } //--------------------------------------------------------------------------- в заключение хотелось бы опять все полученное интуицией и опытами подтвердить стандартом или мнением опытного программиста, что так и должно быть...
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #24 : 20-05-2011 04:57 » |
|
какой грустный код const_cast это страшный зверь, при максимальных уровнях оптимизации поведение программы может быть не детерминированным компилятор может вставлять кэширование const объектов и прочая хрень используй mutable оператор присваивания со свопом внутри это помоему, какая-то подстава для пользователя класса, сделайте метод swap копирующий конструктор не вызвается ибо rvo/nrvo http://alenacpp.blogspot.com/2008/02/rvo-nrvo.html и прочий inline
|
|
|
Записан
|
Странно всё это....
|
|
|
PredatorAlpha
Помогающий
Offline
|
|
« Ответ #25 : 24-05-2011 09:33 » |
|
спасибо большое, Вад, что посмотрели стандарт, это нужно для того, чтобы знать на кого ругаться и материться, если что спасибо также, Вад, что рассказали текущую ситуацию в языках программирования... но именно это и должно нас подталкивать к поиску альтернативных вариантов , чтобы все было просто и красиво Звиняйте что лезу не в свой разговор, но это просто паранойя - не доверять решению, которое было запечатано в стандарте почти двадцать лет тому назад, и не менялось (в сторону уменьшения). Если Вам интересно, как принималось это решение, какие аргументы приводились, из каких вариантов выбиралось - рекомендую книгу Стауструпа "Дизайн и эволюция C++", там в главе "6.3.2. Время жизни объектов" это подробно описано. С примерами, пояснениями.
|
|
|
Записан
|
|
|
|
FeelUs
|
|
« Ответ #26 : 08-08-2011 21:02 » |
|
насколько я на данный момент понял, у объектов нет понятия rvalue и lvalue но есть понятие временный объект - объект, возвращенный из функции по значению, или сконструированный прямо в выражении (разименованный указатель на объект - не является временным объектом) а все дело было в том, что у борланда нельзя передавать временные объекты по неконстантным ссылкам в конструкторы и операторы присваивания, а в другие функции, методы и операторы передавать так можно скачал msvc2008, там это можно => все работает без const_cast'ов и mutabl'ов PS оператор присваивания со свапом - действительно не то, сделал delete lp; lp=x.lp; x.lp=NULL;
|
|
|
Записан
|
|
|
|
PredatorAlpha
Помогающий
Offline
|
|
« Ответ #27 : 11-08-2011 12:41 » |
|
Борланд - это отдельная история...
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #28 : 12-08-2011 04:23 » |
|
Борланд - это отдельная история...
а при чём тут Борлад?
|
|
|
Записан
|
Странно всё это....
|
|
|
|