moving constructor
От: SVV Беларусь  
Дата: 17.11.15 13:00
Оценка:
Всем привет,

пытаюсь сделать класс "строка" (Str, усеченная версия std::string)
есть такой код:
Str s3 = s1+" "+s2;

в данный момент у Str есть operator+ который в итоге создает объект равный "s1+" "+s2" (временный), для создания s3 используется конструктор Str, а как добиться того чтобы вызывался "moving constructor"? а то для выполнения = сначала вызывается конструктор, создающий s3 на основе временного объекта, а потом деструктор, для временного объекта.
использую Visual Studio 2012.
Re: moving constructor
От: watchmaker  
Дата: 17.11.15 13:32
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>а как добиться того чтобы вызывался "moving constructor"?

Реализуй конструктор
Str(Str&& sourceString) {
 ...
}


SVV> а потом деструктор, для временного объекта.

Раз временный объект существует, то придётся его разрушить в любом случае. Другое дело, что можно так написать код, что после перемещения в нём уже может не останется ресурсов, которые нужно освобождать.
Re[2]: moving constructor
От: SVV Беларусь  
Дата: 17.11.15 13:38
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, SVV, Вы писали:


SVV>>а как добиться того чтобы вызывался "moving constructor"?

W>Реализуй конструктор
есть такой, не вызывается.
W>
Str(Str&& sourceString) {
W> ...
W>}

у меня operator+ возвращал const Str& что не правильно. убрав const я убрал временный объект, но тогда операции суммирования стали происходить в объекте s1
Re[3]: moving constructor
От: watchmaker  
Дата: 17.11.15 13:42
Оценка: 2 (1)
Здравствуйте, SVV, Вы писали:

SVV>у меня operator+ возвращал const Str& что не правильно. убрав const я убрал временный объект, но тогда операции суммирования стали происходить в объекте s1


operator+ должен возвращать просто Str, без всяких ссылок, то есть новый объект.
Это обычно operator+= возвращает ссылку (на изменённого себя).
Отредактировано 17.11.2015 13:45 watchmaker . Предыдущая версия .
Re: moving constructor
От: Vamp Россия  
Дата: 17.11.15 13:56
Оценка:
SVV>в данный момент у Str есть operator+ который в итоге создает объект равный "s1+" "+s2" (временный), для создания s3 используется конструктор Str, а как добиться того чтобы вызывался "moving constructor"? а то для выполнения = сначала вызывается конструктор, создающий s3 на основе временного объекта, а потом деструктор, для временного объекта.

Приведи прототипы функций и конструкторов класса.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: moving constructor
От: SVV Беларусь  
Дата: 17.11.15 14:16
Оценка:
Здравствуйте, Vamp, Вы писали:

SVV>>в данный момент у Str есть operator+ который в итоге создает объект равный "s1+" "+s2" (временный), для создания s3 используется конструктор Str, а как добиться того чтобы вызывался "moving constructor"? а то для выполнения = сначала вызывается конструктор, создающий s3 на основе временного объекта, а потом деструктор, для временного объекта.


V>Приведи прототипы функций и конструкторов класса.

Str (const char *sz, st Len=-1);
Str (char *sz, EFlag f, st Len=-1);
Str (const Str &sz);
// move constructor
Str(Str&& temp);
~Str();
Str& operator=(const Str &r);
// move assignment operator
Str& operator=(Str&& temp);
Str& operator+(const Str &r);

жирным в последней строке кода выделил то что уже убрал. и суммирование в s1 прекратилось. оно происходит во временном объекте. move constructor не вызывается
Re[3]: moving constructor
От: Vamp Россия  
Дата: 17.11.15 14:29
Оценка: 2 (1)
Str& operator+(const Str &r);


Вот тут ошибка. operator+ должен быть свободной функцией, вот такой:
Str operator+ (Str lhs, Str rhs) {
    Str tmp(std::move(lhs));
        tmp += rhs;
        return tmp;
}
Да здравствует мыло душистое и веревка пушистая.
Re[4]: moving constructor
От: SVV Беларусь  
Дата: 17.11.15 14:50
Оценка:
Здравствуйте, Vamp, Вы писали:


V>
V>Str& operator+(const Str &r);
V>


V>Вот тут ошибка. operator+ должен быть свободной функцией, вот такой:

V>
V>Str operator+ (Str lhs, Str rhs) {
V>    Str tmp(std::move(lhs));
V>        tmp += rhs;
V>        return tmp;
V>}
V>

спасибо. правда std::move я пока что выбросил. в теле operator+ приходится по-другому действовать (иначе как минимум нужен Str::operator+=).
к тому же, этот std::move приводит к вызову move constructor для s1 (в выражении Str s3(s1+" "+s2) что для меня непонятно.
Re[5]: moving constructor
От: SVV Беларусь  
Дата: 17.11.15 15:08
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>Здравствуйте, Vamp, Вы писали:



V>>
V>>Str& operator+(const Str &r);
V>>


V>>Вот тут ошибка. operator+ должен быть свободной функцией, вот такой:

V>>
V>>Str operator+ (Str lhs, Str rhs) {
V>>    Str tmp(std::move(lhs));
V>>        tmp += rhs;
V>>        return tmp;
V>>}
V>>

SVV>спасибо. правда std::move я пока что выбросил. в теле operator+ приходится по-другому действовать (иначе как минимум нужен Str::operator+=).
SVV>к тому же, этот std::move приводит к вызову move constructor для s1 (в выражении Str s3(s1+" "+s2) что для меня непонятно.
Может быть кто-то знает почему обработка выражения
Str s3(s1+" "+s2);

начинается с вызова
Str::Str (const Str &s)

для s1? т.е. создается дубликат s1...
точнее как избежать создания дубликата, который делается чтобы суммирование не изменило значение s1

updated. все, дошло.
Str operator+ (Str lhs, Str rhs)

надо заменить на
Str operator+ (const Str &lhs, const Str &rhs)
Отредактировано 17.11.2015 15:27 SVV . Предыдущая версия . Еще …
Отредактировано 17.11.2015 15:12 SVV . Предыдущая версия .
Re[4]: moving constructor
От: Константин Россия  
Дата: 18.11.15 16:32
Оценка:
Здравствуйте, Vamp, Вы писали:


V>
V>Str& operator+(const Str &r);
V>


V>Вот тут ошибка. operator+ должен быть свободной функцией, вот такой:

V>
V>Str operator+ (Str lhs, Str rhs) {
V>    Str tmp(std::move(lhs));
V>        tmp += rhs;
V>        return tmp;
V>}
V>


Можно даже так
Str operator+ (Str lhs, Str rhs) {
        lhs += rhs;
        return lhs;
}
Re[5]: moving constructor
От: Vamp Россия  
Дата: 18.11.15 17:53
Оценка:
К>Можно даже так
Str operator+ (Str lhs, Str rhs) {
        lhs += rhs;
        return lhs;
}


Так хуже — не будет шанса на NRVO.
Да здравствует мыло душистое и веревка пушистая.
Re[6]: moving constructor
От: Константин Россия  
Дата: 18.11.15 18:15
Оценка:
Здравствуйте, Vamp, Вы писали:

К>>Можно даже так

V>
V>Str operator+ (Str lhs, Str rhs) {
V>        lhs += rhs;
V>        return lhs;
V>}
V>


V>Так хуже — не будет шанса на NRVO.


А есть ли разница? Если не будет NRVO, то случится move. В случае переменной temp, этот move уже есть.

NRVO:
lhs => move to destination
destination += rhs

no NRVO:
lhs += rhs
lhs => move to destination
Re[7]: moving constructor
От: Vamp Россия  
Дата: 18.11.15 18:56
Оценка:
К>А есть ли разница? Если не будет NRVO, то случится move. В случае переменной temp, этот move уже есть.
Тоже правда. Код c точки зрения результата эквивалентен. Готов признать, что твой чуть краше смотрится.
Да здравствует мыло душистое и веревка пушистая.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.