Допустим, есть объект, для которого надо реализовать оператор +.
Как это лучше всего сделать?
— возвращать его по значению (но тогда ведь будет происходить копирование и копирующее присваивание)
— возвращать указатель на него (но тогда прийдётся записывать выражение для указателей, а не для объектов, типа
pA = pB + pC вместо a = b + c)
— возвращать ссылку на динамическую переменную (но как тогда пользователь догадается о необходимости уничтожения?)
И вообще, напишите, что конкретно будет происходить, а также что должно быть выполнено до и после конструкции
a = b + c.
Сразу ли результат будет положен в a, или сначала он будет вычислен, а потом будет применён оператор =?
В общем, распишите подробнее...
Здравствуйте, Аноним, Вы писали:
А>Допустим, есть объект, для которого надо реализовать оператор +. А>Как это лучше всего сделать?
А>- возвращать его по значению (но тогда ведь будет происходить копирование и копирующее присваивание) А>- возвращать указатель на него (но тогда прийдётся записывать выражение для указателей, а не для объектов, типа А>pA = pB + pC вместо a = b + c) А>- возвращать ссылку на динамическую переменную (но как тогда пользователь догадается о необходимости уничтожения?)
А>И вообще, напишите, что конкретно будет происходить, а также что должно быть выполнено до и после конструкции А>a = b + c.
А>Сразу ли результат будет положен в a, или сначала он будет вычислен, а потом будет применён оператор =? А>В общем, распишите подробнее...
Если большой объект — контейнер, то на эту тему можно прочитать по крайней мере в двух книжках:
1. Джосаттис и Вандевурд. Шаблоны в С++
2. Брюс Эккель. Философия С++.
Тема называется " шаблоны выражений" и относится к метапрограммированию на С++. Тема сложная, поэтому так просто объяснить — не получится. Если просто реализовывать операции — получается не очень эффективно из-за постоянного создания и уничтожения временных объектов.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Большие объекты и операторы.
От:
Аноним
Дата:
20.10.04 16:11
Оценка:
И ещё вопрос:
корректно ли так:
T& fun(T& a, T& b)
{
T c;
...
return c;
}
Re[2]: Большие объекты и операторы.
От:
Аноним
Дата:
20.10.04 16:13
Оценка:
Здравствуйте, LaptevVV, Вы писали:
LVV>Здравствуйте, Аноним, Вы писали:
А>>Допустим, есть объект, для которого надо реализовать оператор +. А>>Как это лучше всего сделать?
А>>- возвращать его по значению (но тогда ведь будет происходить копирование и копирующее присваивание) А>>- возвращать указатель на него (но тогда прийдётся записывать выражение для указателей, а не для объектов, типа А>>pA = pB + pC вместо a = b + c) А>>- возвращать ссылку на динамическую переменную (но как тогда пользователь догадается о необходимости уничтожения?)
А>>И вообще, напишите, что конкретно будет происходить, а также что должно быть выполнено до и после конструкции А>>a = b + c.
А>>Сразу ли результат будет положен в a, или сначала он будет вычислен, а потом будет применён оператор =? А>>В общем, распишите подробнее... LVV>Если большой объект — контейнер, то на эту тему можно прочитать по крайней мере в двух книжках: LVV>1. Джосаттис и Вандевурд. Шаблоны в С++ LVV>2. Брюс Эккель. Философия С++. LVV>Тема называется " шаблоны выражений" и относится к метапрограммированию на С++. Тема сложная, поэтому так просто объяснить — не получится. Если просто реализовывать операции — получается не очень эффективно из-за постоянного создания и уничтожения временных объектов.
Да, контейнер...
А вообще, есть идея оставить только +=, -=, *=, чтобы хотя бы было ясно, что происходит
Здравствуйте, Аноним, Вы писали:
А>И ещё вопрос:
А>корректно ли так:
А>
А>T& fun(T& a, T& b)
А>{
А> T c;
А> ...
А> return c;
А>}
А>
Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Большие объекты и операторы.
От:
Аноним
Дата:
20.10.04 16:29
Оценка:
Здравствуйте, LaptevVV, Вы писали:
LVV>Здравствуйте, Аноним, Вы писали:
А>>И ещё вопрос:
А>>корректно ли так:
А>>
А>>T& fun(T& a, T& b)
А>>{
А>> T c;
А>> ...
А>> return c;
А>>}
А>>
LVV>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола.
А как тогда реализуются операторы для больших объектов, возвращающие ссылки?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, LaptevVV, Вы писали:
LVV>>Здравствуйте, Аноним, Вы писали:
А>>>И ещё вопрос:
А>>>корректно ли так:
А>>>
А>>>T& fun(T& a, T& b)
А>>>{
А>>> T c;
А>>> ...
А>>> return c;
А>>>}
А>>>
LVV>>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола. А>А как тогда реализуются операторы для больших объектов, возвращающие ссылки?
1. функция может вернуть ссылку, если она ее получила как параметр
2. можно вернуть ссылку на статическую переменную
3. можно вернуть ссылку на динамическую переменную — только пример попроси привести действующих програмистов — у меня под рукой нет, а они на практивке это делают.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: Большие объекты и операторы.
От:
Аноним
Дата:
20.10.04 16:38
Оценка:
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола. А>>А как тогда реализуются операторы для больших объектов, возвращающие ссылки? LVV>1. функция может вернуть ссылку, если она ее получила как параметр LVV>2. можно вернуть ссылку на статическую переменную LVV>3. можно вернуть ссылку на динамическую переменную — только пример попроси привести действующих програмистов — у меня под рукой нет, а они на практивке это делают.
В конкретном примере нужно вернуть ссылку на некоторый новый объект.
1 — не подходит,
3 — тогда вряд ли будет выглядеть красивым delete &с где-то в программе.
Остаётся второе.
А вообще, в таких случаях это хорошо?
Re[6]: Большие объекты и операторы.
От:
Аноним
Дата:
20.10.04 16:42
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, LaptevVV, Вы писали:
LVV>>>>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола. А>>>А как тогда реализуются операторы для больших объектов, возвращающие ссылки? LVV>>1. функция может вернуть ссылку, если она ее получила как параметр LVV>>2. можно вернуть ссылку на статическую переменную LVV>>3. можно вернуть ссылку на динамическую переменную — только пример попроси привести действующих програмистов — у меня под рукой нет, а они на практивке это делают. А>В конкретном примере нужно вернуть ссылку на некоторый новый объект. А>1 — не подходит, А>3 — тогда вряд ли будет выглядеть красивым delete &с где-то в программе. А>Остаётся второе. А>А вообще, в таких случаях это хорошо?
Мне кажется, что нехорошо... ведь в памяти может повиснуть в результате куча статических переменных.
Здравствуйте, Аноним, Вы писали:
А>Допустим, есть объект, для которого надо реализовать оператор +. А>Как это лучше всего сделать?
канонический вид бинарного оператора + такой:
T operator+(const T& lhs, const T& rhs)
{
T temp( lhs );
temp += rhs;
return temp;
}
заметь что он реализуется через operator +=
Хороший обзор возможных реализаций operator + даётся здесь
в принципе, при такой реализации можно понадеятся на NRVO (named return value optimization), которая поможет избежать создания временной переменной.
про RVO/NRVO можно почитать здесь
А>И вообще, напишите, что конкретно будет происходить, а также что должно быть выполнено до и после конструкции А>a = b + c.
хорошо это описал Павел Кузнецов здесь
Здравствуйте, Аноним, Вы писали:
А>Допустим, есть объект, для которого надо реализовать оператор +. А>Как это лучше всего сделать?
А>- возвращать его по значению (но тогда ведь будет происходить копирование и копирующее присваивание) А>- возвращать указатель на него (но тогда прийдётся записывать выражение для указателей, а не для объектов, типа А>pA = pB + pC вместо a = b + c) А>- возвращать ссылку на динамическую переменную (но как тогда пользователь догадается о необходимости уничтожения?)
А>И вообще, напишите, что конкретно будет происходить, а также что должно быть выполнено до и после конструкции А>a = b + c.
А>Сразу ли результат будет положен в a, или сначала он будет вычислен, а потом будет применён оператор =? А>В общем, распишите подробнее...
Есть еще такой подход.
Допустим есть класс Heavy с оч. тяжелой операцией копирования.
Хочется сделать operator+ подешевле, и что б работало без оглядки на возможности компилятора по оптимизации.
Здравствуйте, Аноним, Вы писали:
LVV>>>>>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола. А>>>>А как тогда реализуются операторы для больших объектов, возвращающие ссылки? LVV>>>1. функция может вернуть ссылку, если она ее получила как параметр LVV>>>2. можно вернуть ссылку на статическую переменную LVV>>>3. можно вернуть ссылку на динамическую переменную — только пример попроси привести действующих програмистов — у меня под рукой нет, а они на практивке это делают. А>>В конкретном примере нужно вернуть ссылку на некоторый новый объект. А>>1 — не подходит, А>>3 — тогда вряд ли будет выглядеть красивым delete &с где-то в программе. А>>Остаётся второе. А>>А вообще, в таких случаях это хорошо?
А>Мне кажется, что нехорошо... ведь в памяти может повиснуть в результате куча статических переменных.
Еще можно почитать про "ленинвые вычисления" или отложенное присваивание — у Мейерса, например в его книжках-советах. Там тоже как раз на больших объектах это объясняется — на матрицах.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
это применимо при работе с одним потоком, в противном случае прийдется синхронизировать работу данного метода, что будет ИМХО тяжелее чем возврат временного объекта по значению
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, Аноним, Вы писали:
А>>Мне кажется, что нехорошо... ведь в памяти может повиснуть в результате куча статических переменных.
ssm>ну почему же куча? всего один на класс
Со всеми вытекающими
например для такого кода
class A {
//...
}
const A& operator+(const A& left, const A& right)
{
static A result;
//...return A;
}
// где-то в коде
A a, b, c, d;
//...
A result = (a + b) * (c + d);
Результату будет не хорошо.
Итого ссылка на статическую переменную не годится. Второй вариант от безысходности — статический массив — душим на корню без рассуждений.
Итого остается — возврат по значению. Или, если это совсем не катит по соображениям эффективности, то "отложенное присваивание"
Здравствуйте, LaptevVV, Вы писали:
LVV>Вообще-то — грубая ошибка для любого конкретного типа — возвращается ссылка на локальный объект. Последствия — непредсказуемы. Но с шаблонами у меня опыт небольшой, поэтому не могу определенно сказать, может сущетсуют ситуации. когда такая запись прокатит. Тебе гури наши точней скажут. Вс-таки, ИМХО, это крамола.
Дык...шаблоны/не шаблоны — ересь однозначно — возвращаем-то ведь действительно ссылку на локальный объект...