LINUX.ORG.RU

вопрос по С++


0

0

у Страуструпа читаем о перегрузке опирации +

class Vec; // Vec - имя класса

class vector {

friend Vec operator+(Vec, Vec);

//...

};

Vec operator+(Vec a, Vec b)

{

int s = a.size();

if (s != b.size()) error("плохой размер вектора для +");

Vec& sum = *new Vec(s);

int* sp = sum.v;

int* ap = a.v;

int* bp = b.v;

while (s--) *sp++ = *ap++ + *bp++;

return sum;

}

разве использование new в этом случае не приведёт к утечки памяти?

Vec a,b,s;

....

s = a + b;

....

я не вижу где в этом примере произойдёт удаление временного объекта. Может я что не так понимаю, подскажите где...

anonymous

по моему это довольно неудачный пример. И конечно память будет течь.

Хотя можно предположить, что у Vec вообще нет членов и он не занимает памяти????

Это предположение оправдывает постоянное копирование при вызове и возврате значения из

Vec operator+(Vec a, Vec b)

Но, скорее всего, это просто грубые ошибки в дизайне.

anonymous
()
Ответ на: комментарий от flamer

> Дык это твоя должна быть забота - удалить s.

фишка в том что в s будет храниться лишь копия результата сумирования (копия поэлементная, если иного не предусмотрено переопеределённой опирацией =), поэтому добраться до элемента созданного new не представляется возможным, если только его где-то отдельно не сохранять (если так делать а потом самому удалять это не объктный подход а чёрте что).

Да согласен пример не удачный, но это пример из Страуструпа, вот что..... А подскажите как грамотно перегрузить опирацию +(только не +=, а именно +)?

anonymous
()
Ответ на: комментарий от anonymous

Type operator+(Type &ob) {
return ob+*this;
}

Желательно, чтобы для Type был конструктор копии.

Envel ★★★
()
Ответ на: комментарий от anonymous

> как грамотно перегрузить опирацию +
Если нужны вектора или всякие там матрицы, то проще всего взять их
готовыми. Например с boost.org библиотека boost/numeric/ublas.
Там, кстати, операция + очень красиво, но достаточно сложно перегружена.

Если нужно, что то свое сделать по принципу дешево и эффективно, то
я бы использовал, что то типа:

typedef std::vector<MyClass> Vector;
typedef boost::shared_ptr<Vector> Vector;
VectorPtr plus( const Vector& a; const Vector& b)
{
  //добавь всякие проверки по вкусу ...
  boost::shared_ptr<Vector> resL(new Vector);
  std::transform(a.begin(),a.end(),b.begin(), std::back_inserter(*resL), std::plus<MyClass>());
  return resL;
}
Но если все же душа просит c=a+b, то можно сделать например так
std::list<VectorPtr> globalList;
Vector&
operator+ (const Vector& a; const Vector& b)
{
   globalList.push_back( plus(a,b));
   return *globalList.back();
}

anonymous
()
Ответ на: комментарий от anonymous

typedef boost::shared_ptr<Vector> Vector;
читать как
typedef boost::shared_ptr<Vector> VectorPtr;

anonymous
()
Ответ на: комментарий от anonymous

> А подскажите как грамотно перегрузить опирацию +(только не +=, а именно +)? 

Грамотно - это всегда перегружать их обе.  "+=" - членом класса, "+" - членом класса или свободной ф-ией - это дело вкуса, но определять её в любом случае через "+="

struct foo {
  const foo& operator+=(const foo &rhs) {
     // bla-bla-bla
     return *this;
  }
};

const foo operator+(const foo &rhs, const foo &lhs) {
  foo foo_(rhs);
  return (foo_ += lhs);
}

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

Ron
()
Ответ на: комментарий от Ron

>const foo operator+(const foo &rhs, const foo &lhs)

все это абсолютно верно, но проблема заключается, что происходит ненужное копирование объекта foo. А для векторов это довольно дорого... Поэтому и приходится выкручиваться

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.