Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> перегрузка оператора 
:(
    Опции темы
iff
Дата 12.5.2013, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: нет
Всего: 16



Когда нужно использовать ссылки а когда нет?

A - это класс
Код

A operator-() const;
friend A operator-(const A&, const A&);
A& operator-=(const A&);

при это -= написан так:
Код

A& A::operator-=(const A &x) {
    return *this = *this - x;
};

может быть если возвращаемый результат ссылка (в примере с -=), то новый объект удаляется и возвращается ссыка на старый, но изменённый (return *this)?
при этом если возвращать ссылку в операторе -, то возникает предупреждение что она указывает на локальную переменную (там создаётся др. объект)


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
mes
Дата 12.5.2013, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(iff @  11.5.2013,  23:39 Найти цитируемый пост)
 то новый объект удаляется и возвращается ссыка на старый,

какой новый ? именно, что нового не создается, а возврашается ссылка на измененный..

Добавлено через 19 секунд
Цитата(iff @  11.5.2013,  23:39 Найти цитируемый пост)
 то возникает предупреждение что она указывает на локальную переменную (там создаётся др. объект) 

 smile 


--------------------
PM MAIL WWW   Вверх
volatile
Дата 13.5.2013, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(iff @  12.5.2013,  00:39 Найти цитируемый пост)
при это -= написан так:
A& A::operator-=(const A &x) {
    return *this = *this - x;
};

Лучше делать наоборот.
написать только оператор -=, а оператор - выражать через него.

Цитата(iff @  12.5.2013,  00:39 Найти цитируемый пост)
Когда нужно использовать ссылки а когда нет?

Цитата(iff @  12.5.2013,  00:39 Найти цитируемый пост)
A operator-() const;
friend A operator-(const A&, const A&);
A& operator-=(const A&);

Вот как у вас написано, так и нужно. (только первый, это унарный минус. он немножко здесь не к месту.)


PM MAIL   Вверх
borisbn
Дата 13.5.2013, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(volatile @  13.5.2013,  00:13 Найти цитируемый пост)
написать только оператор -=, а оператор - выражать через него.

 smile как ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 13.5.2013, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Лучше наверно так:
Код

class A {
public:
A operator-() const;
friend A operator-(const A&, const A&);
A& operator-=(const A&);
private:
void subtract(A& z, const A& x, const A& y);
int value;
};

A& A::operator-=(const A &x) {
    A::subtract(*this,*this, x);
    return *this;
};
A operator-(const A& x, const A&y) {
    A z;
    A::subtract(z, x, y);
    return z;
}
void A::subtract(A& z, const A& x, const A& y) {
    z.value = x.value - y.value;
}


Это сообщение отредактировал(а) math64 - 13.5.2013, 09:44
PM   Вверх
borisbn
Дата 13.5.2013, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



math64, тогда уж substract д.б. static

Это сообщение отредактировал(а) borisbn - 13.5.2013, 10:35


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldina
Дата 13.5.2013, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(volatile @  13.5.2013,  00:13 Найти цитируемый пост)
Лучше делать наоборот.

да и так, и так нормально. разница вкусовая (естественно, в обоих случаях можно обойтись без friend и статических функций)

Цитата(borisbn @  13.5.2013,  09:30 Найти цитируемый пост)
Цитата(volatile @  13.5.2013,  00:13 )
написать только оператор -=, а оператор - выражать через него.

  как ? 

Код

class Foo {
  public:
   Foo& operator-=(const Foo& other);
};

Foo operator-(const Foo& lhs, const Foo& rhs) {
  Foo temp(lhs);
  temp -= rhs;
  return temp;
}


Добавлено через 1 минуту и 52 секунды
кстати, см. boost::operators, там так и сделано
PM MAIL   Вверх
volatile
Дата 13.5.2013, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(baldina @  13.5.2013,  10:57 Найти цитируемый пост)
да и так, и так нормально. разница вкусовая 

не совсем вкусовая.
оператор-= более естествен, и его можно написать с меньшим оверхедом.

Цитата(iff @  12.5.2013,  00:39 Найти цитируемый пост)
A& A::operator-=(const A &x) {
    return *this = *this - x;
};

здесь создание лишнего временного экземпляра, лишний оператор присваивания, и лишнее удаление временного экземпляра.


PM MAIL   Вверх
baldina
Дата 13.5.2013, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(volatile @  13.5.2013,  13:05 Найти цитируемый пост)
оператор-= более естествен

согласен, и мне так больше нравится. но таки это вкусовой вопрос))

Цитата(volatile @  13.5.2013,  13:05 Найти цитируемый пост)
и его можно написать с меньшим оверхедом.

Код

class Foo {
  public:
   Foo& operator+=(const Foo& other);
};
Foo operator+(const Foo& lhs, const Foo& rhs) {
  Foo temp(lhs);
  temp += rhs;
  return temp;
}

vs
Код

class Foo {
  public:
   Foo operator+(const Foo& other) const;
};
Foo& operator+=(Foo& lhs, const Foo& rhs) {
  return lhs = lhs+rhs;
}

при использовании дадут практически идентичный код

Добавлено @ 14:09
тут скорее разница в том, что в случае 
Код

Foo Foo::operator+(const Foo& other) const;

может не получится неявного преобразования, требуются ужимки и прыжки
Скажем, 
Код

class Foo {
  Foo(int);
  Foo operator+(const Foo& other) const;
};
...
Foo foo0=1;
Foo foo1 = foo0+1; // ok
Foo foo2 = 1+foo0; // ups

поэтому лучше предпочитать Foo::operator+=(const Foo&);

Это сообщение отредактировал(а) baldina - 13.5.2013, 16:37
PM MAIL   Вверх
NoviceF
Дата 13.5.2013, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(baldina @  13.5.2013,  15:01 Найти цитируемый пост)
при использовании дадут практически идентичный код

Насколько я понимаю, в первом варианте очепятка
Код

operator-


Цитата(baldina @  13.5.2013,  15:01 Найти цитируемый пост)
согласен, и мне так больше нравится. но таки это вкусовой вопрос))

Но, если верить Саттеру, 1й вариант это всётаки каноническая форма
http://programming-lang.com/ru/comp_progra...tter/0/j55.html
PM MAIL   Вверх
baldina
Дата 13.5.2013, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(NoviceF @  13.5.2013,  16:27 Найти цитируемый пост)
в первом варианте очепятка

да, исправил
Цитата(NoviceF @  13.5.2013,  16:27 Найти цитируемый пост)
Но, если верить Саттеру

Саттеру верить можно, но молиться не стоит))
PM MAIL   Вверх
baldina
Дата 13.5.2013, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



перечитал по ссылке, вижу что
1. под канонической формой он понимает взаимосвязь (в т.ч. связанное определение) operator оп() и operator оп=(). у нас это подразумевается и выполняется в обоих случаях
2. имеется упоминание неявных преобразований, о которых я упоминал
Цитата

Обратите внимание, что здесь operator@ — функция-не член, так что она обладает желательным свойством возможности неявного преобразования как левого, так и правого параметра

3. как вариант приводится и вторая форма
Цитата

T& operator@=(T& lhs, const T& rhs) {
 // ... реализация ...
 return lhs;
}

и
Цитата

В некоторых случаях (например, оператор operator*= для комплексных чисел), оператор может изменять левый аргумент настолько существенно, что более выгодным может оказаться реализация оператора operator*= посредством оператора operator*, а не наоборот.


В общем я принципиальных отличий от своего поста не вижу. Думаю, еще надо учесть, что писалось это 10лет назад, с тех пор оптимизаторы несколько ушли вперед (например хорошо научились делать NRVO), и некоторые соображения эффективности уже не играют существенной роли.

Тем не менее форма с operator@= членом класса и свободной функцией operator@, реализованной через первый оператор, мне импонирует больше, т.к. позволяет меньше думать о преобразованиях и эффективности, поэтому, если не используются boost::operators, ей следует отдавать предпочтение. Не забывая, что этот вариант не является единственно правильным))
PM MAIL   Вверх
NoviceF
Дата 13.5.2013, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(baldina @  13.5.2013,  18:01 Найти цитируемый пост)
В общем я принципиальных отличий от своего поста не вижу.

Так я о принципиальных отличиях и не писал smile Однако, всёже, на мой взгляд, каноническим называется именно способ реализации @ через @=, т.к.:

"В общем случае для некоторого бинарного оператора @ (+, -, * и т.д.) вы должны также определить его присваивающую версию, так чтобы a@=b и a=a@b имели один и тот же смысл (причем первая версия может быть более эффективна). Канонический способ достижения данной цели состоит в определении @ посредством @= следующим образом:.."
PM MAIL   Вверх
volatile
Дата 13.5.2013, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(baldina @  13.5.2013,  14:01 Найти цитируемый пост)
при использовании дадут практически идентичный код


baldina, в общем случае не дадут идентичный код.
я уже писал, там создание лишнего объекта, лишний оператор присваивания.
Возможности оптимизатора не безграничны. и он далеко не для всех типов может удалить конструктор, оператор присваивания и деструктор.
А для сложных типов, эти функции могут быть достаточно ресурсоемки.
Оператор+= можно написать, в большинстве случаев без создания временной переменной.
если же мы его выражаем через оператор+, то без создания временной переменной не обойтись.


Это сообщение отредактировал(а) volatile - 13.5.2013, 19:58
PM MAIL   Вверх
borisbn
Дата 14.5.2013, 06:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Господа опытные программисты, когда вы в последний раз переопределяли операторы -=() и/или -() в боевом проекте? Что это был за класс? Я, наверное, недостаточно опытный, т.к. не могу вспомнить, когда мне это было необходимо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 14.5.2013, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Я это делал, когда писал с++ обертку для bigdigits.
В принципе, переопределение данного операторов (да и всех математических) имеет смысл только для матемаических классов.
PM   Вверх
baldina
Дата 14.5.2013, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(borisbn @  14.5.2013,  06:00 Найти цитируемый пост)
когда вы в последний раз переопределяли операторы -=() и/или -() в боевом проекте?

не так часто, конечно)) обычно алгебра, bsa прав
из последних - классы математических выражений для отображения хода вычислений, года три назад. давно как-то приходилось вектора/матрицы писать

Добавлено через 6 минут и 44 секунды
еще (довольно давно) были классы для вычислений с учетом размерностей
иногда возникают небольшие задачи с использованием operator+ специального вида для строк (вроде конкатенации с добавлением разделителя)

Добавлено через 10 минут и 21 секунду
Цитата(volatile @  13.5.2013,  19:56 Найти цитируемый пост)
там создание лишнего объекта, лишний оператор присваивания

пара 
Код

a+=b
c=a+b

по идее должны давать одинаковый код при любой реализации. конечно, это от самих классов и компилятора зависит...
давайте проведем эксперимент: предлагайте (разумную) семантику operator+() в конкретном, гипотетически полезном случае - сравним
PM MAIL   Вверх
bsa
Дата 14.5.2013, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Обычно, оператор + реализуется через +=:
Код
class MyClass
{
...
    MyClass& operator+=(const MyClass &o) {
         ...
         return *this;
    }
...
};

MyClass operator+(const MyClass &o1, const MyClass &o2)
{
   MyClass ret(o1);
   ret += o2;
   return ret;
}

PM   Вверх
volatile
Дата 14.5.2013, 17:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(baldina @  14.5.2013,  10:06 Найти цитируемый пост)
предлагайте (разумную) семантику operator+() в конкретном, гипотетически полезном случае - сравним 

Ну хорошо.
Давайте, чтоб не скучно было, выведем первую тыщу чисел фибоначчи.
Код конечно далёк от оптимального, (например. в чаре храницца только число в диапазоне [0..9], ну да суть не в этом.
Код

#include <iostream>
#include <iomanip>
typedef unsigned ui;
typedef unsigned char u8;

// Для другого варианта закомментировать эту строчку =>
#define BALDINA_VARINT

class big_num
{
public:
   static const ui SIZE = 220;
   big_num (ui v = 0)
   {
      for (ui i = 0; i < SIZE; ++ i)
      {
         data [i] = v % 10;
         v /= 10;
      }
   }

   ~ big_num () {++ object_counter;} // объекты подсчитываем в деструкторе, потому-что конструкторов много, и не все видны.
   static ui object_counter;

   friend std::ostream & operator << ( std::ostream & os, const big_num & v)
   {
      bool leading_zeros = 1;
      for (ui i = 0; i < SIZE; ++ i)
      {
         ui j = SIZE - i - 1;
         if (!leading_zeros || v.data [j] || j == 0)
         {
            os << char('0' + v.data [j]);
            leading_zeros = 0;
         }
         // else
         //    os << ' ';
      }
      return os;
   }

   // -------------------------------------------
   // ----------- Начинаюцца Варианты -----------
#ifdef BALDINA_VARINT
   big_num operator + (const big_num & r) const
   {
      big_num t;
      ui carry = 0;
      for (ui i = 0; i < SIZE; ++ i)
      {
         ui val = data [i] + r.data [i] + carry;
         t.data[i] = val % 10;
         carry = val / 10;
      }
      return t;
   }

   big_num & operator += (const big_num & r)
   {
       return *this = *this + r;
   }

#else

   big_num operator + (const big_num & r) const
   {
      big_num t (*this);
      t += r;
      return t;
   }

   big_num & operator += (const big_num & r)
   {
      ui carry = 0;
      for (ui i = 0; i < SIZE; ++ i)
      {
         ui val = data [i] + r.data [i] + carry;
         data[i] = val % 10;
         carry = val / 10;
      }
      return *this;
   }
#endif
   // ----------- Конец Вариантов ---------------
   // -------------------------------------------

private:
   u8 data [SIZE];
};

ui big_num::object_counter = 0;

void fib ()
{
   big_num a (1);
   big_num b (0);
   ui num = 0;
   for (int i = 0; i < 500; ++ i)
   {
      a += b;
      std::cout << std::setw(5) << ++ num << " : " << a << std::endl;
      b = a + b;
      std::cout << std::setw(5) << ++ num << " : " << b << std::endl;
   }
}

int main ()
{
   fib ();
   
   // здесь все объекты удалены, можно вывести количесво.
   std::cout << "objects: " << big_num::object_counter;
}

Будем подсчитывать кол-во созданных объектов big_num, потребовавшихся для вычисления.
в первом варианте (BALDINA_VARINT)
сорри за имя 'BALDINA_VARINT', что-то ничего больше не пришло больше в голову. переименуйте как вам угодно.
Код
objects: 1002
во втором варианте ()
Код
objects: 502

На gcc и в студии одинаково.
В студии была максимальная оптимизация на скорость + Use Link Time Code Generation

Добавлено через 7 минут и 6 секунд
Попробовал на codepad.org.
Тыщу чисел он не смог переварить, уменьшил в 10 раз

http://codepad.org/02MJuOJS
http://codepad.org/Ol4LplTE
objects: 202 
objects: 102 

но там без оптимизации.
На домашнем компе
objects: 102
objects: 52

В любом случае разница в 2 раза количества объектов сохраняецца. smile 
PM MAIL   Вверх
baldina
Дата 15.5.2013, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



да, все верно  smile
пример мог быть и попроще, если деструкторами измерять, доп объект всегда присутствует.
кстати, вариант со свободной функцией operator+(), некоторыми компиляторами оптимизируется хуже, чем с членом класса.

интересно, что (в данном конкретном случае), компилятор таки умудряется обходиться без фактического "лишнего копирования":
Код

/* b = a + b; */
012F1340  lea         eax,[ebp-1D0h]  
012F1346  push        eax  
012F1347  lea         ecx,[ebp-2B0h]  
012F134D  push        ecx  
012F134E  lea         eax,[ebp-0F0h]  
012F1354  call        big_num::operator+ (12F1060h)  
012F1359  inc         dword ptr [big_num::object_counter (12F4370h)]  

здесь от временного объекта только один след - изменение деструктором object_counter
сравните с явно определенным operator=()
Код

/* b = a + b; */
002B1344  lea         eax,[ebp-1D0h]  
002B134A  push        eax  
002B134B  lea         ecx,[ebp-2B0h]  
002B1351  push        ecx  
002B1352  lea         eax,[ebp-0F0h]  
002B1358  call        big_num::operator+ (2B1060h)  
002B135D  push        0DCh  
002B1362  push        eax  
002B1363  lea         edx,[ebp-1D0h]  
002B1369  push        edx  
002B136A  call        dword ptr [__imp__memmove (2B30D0h)]  
002B1370  inc         dword ptr [big_num::object_counter (2B4370h)]  
002B1376  add         esp,0Ch  


Это сообщение отредактировал(а) baldina - 15.5.2013, 14:05
PM MAIL   Вверх
bsa
Дата 15.5.2013, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(baldina @  15.5.2013,  15:05 Найти цитируемый пост)
кстати, вариант со свободной функцией operator+(), некоторыми компиляторами оптимизируется хуже, чем с членом класса.
К сожалению, вариант с членом класса менее гибок. Например, если суммируются объекты разных типов, но один из них может быть неявно создан из второго (конструктор соответствующий есть). То в этом случае вариант с внешним оператором будет поддерживать и a+b, и b+a, а вот вариант со встроенным - только a+b.
PM   Вверх
volatile
Дата 15.5.2013, 18:50 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(baldina @  15.5.2013,  14:05 Найти цитируемый пост)
если деструкторами измерять,

кол-во деструкторов == равно кол-ву констукторов == кол-ву объектов.
деструкторами измерялось только в силу удобства определения в одном месте.

Цитата(baldina @  15.5.2013,  14:05 Найти цитируемый пост)
сравните с явно определенным operator=()

Хорошо, хотя это не совсем корректно по сравнению с кол-вом объектов.
Цитата(volatile @  14.5.2013,  17:45 Найти цитируемый пост)
   ~ big_num () {++ object_counter;} // объекты подсчитываем в деструкторе, потому-что конструкторов много, и не все видны.
   big_num & operator = (const big_num & r) 
   { ++ object_counter;
      memcpy (data, r.data, SIZE);
      return *this;
   }


Тем не менее, операторов присваивания, как и деструкторов в 2 раза больше:
Код

objects: 1000
objects: 500


 smile 

Это сообщение отредактировал(а) volatile - 15.5.2013, 18:52
PM MAIL   Вверх
bsa
Дата 15.5.2013, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Кстати, оператор присваивания рекомендуется делать через операцию swap.  smile 
Код
MyClass& MyClass::operator=(const MyClass &other)
{
  MyClass(other).swap(*this);
  return *this;
}

PM   Вверх
volatile
Дата 15.5.2013, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(bsa @  15.5.2013,  20:21 Найти цитируемый пост)
рекомендуется делать через операцию swap.

bsa, чтоб делать через swap, нужно сначала написать этот swap  smile 
И кстати, даже если решицца писать его,  то для данного конкретного класса, swap априори будет менее эффективен чем memcpy.
Так что слепо следовать рекомендациям, далеко не всегда оправдано.


Цитата(baldina @  15.5.2013,  14:05 Найти цитируемый пост)
компилятор таки умудряется обходиться без фактического "лишнего копирования":

baldina, в общем как я понял, вы хотите сказать, что не смотря на разницу в количестве объектов, 
операторов присваивания, деструкторов и прочих сишних прибамбасов,
компилятор, каким-то неведомым, волшебным способом делает так, что код, всё равно выполняецца за одинаковое время...

Ну чтож, давайте (чтоб уже добить тему) измерим и время...

Время в миллионах тиков процессора.
(по 3 измерения на каждый вариант)

Первый вариант
Код

#define BALDINA_VARINT
20.6379
20.6013
20.5993


Второй вариант 
Код

// #define BALDINA_VARINT
13.5428
13.393
13.3941

Весь проект для 2008-ой студии (без бинарников).

 smile 


Это сообщение отредактировал(а) volatile - 15.5.2013, 23:53

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  operators.7z 3,98 Kb
PM MAIL   Вверх
bsa
Дата 16.5.2013, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Да. Не обратил внимания. Обычно, такое через динамические массивы делают.
PM   Вверх
baldina
Дата 17.5.2013, 12:10 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Доберусь до компа, погляжу.
Да, я имел в виду что в частных случаях (частых для математических классов) результат может быть одинаков за счет оптимизации. В общем конечно нет, если требуется вызывать сложные конструкторы/деструкторы
Как уже говорил, я сам за каноническую форму, просто хотелось побудить к размышлению и расставить все точки.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0874 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.