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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Возвращение значения перегруженым оператором 
V
    Опции темы
ller
Дата 14.7.2009, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Код

class Matrix
{
private:
    double **matrix;
public:
   Matrix(int x=0,int y=0); // Конструктор выделяет память...
   friend Matrix & operator *(const Matrix &m1,const Matrix &m2); 
   double operator[][](int i,int j) // Такой оператор как можно сделать?
   ~Matrix();
}

Matrix & operator *(const Matrix & m1,const Matrix &m2)
{
    
    Matrix result(m2.x,m1.y);

// тут делаем то что надо, умножаем матрицы...

    return Matrix(result); // Как мернуть значение, чтоб оно не терялось и не дублировалось
}

int main()
{
   Matrix m1(3,3), m2(3,3); // инициализируем 2 матрицы
   Matrix m3;
 
   m3=m1*m2; 
}


Если в методе умножения выделю память разыменую и верну, то объект сам не уничтожется в последствии.
Будем считать что существует копирующий конструктор и оператор присваивания правильные, с учетом указателей, чтоб не загромождать код тут smile
PM MAIL   Вверх
ISergeyN
Дата 14.7.2009, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

 double operator[][](int i,int j) // Такой оператор как можно сделать?

Я  предложил бы так сделать
Код

#include <iostream>

class Employee{
    int arr[10][10];
public:
    Employee(){
        for(int i = 0; i < 10; ++i)
            for(int j = 0; j < 10; ++j)
                arr[i][j] = j + i;
    }

    int operator () (int i, int j) const {
        return arr[i][j];
    }
};
int main()
{  
    Employee e;
     
    std::cout << e(1,3) << std::endl;

    return 0;
}
 

Это сообщение отредактировал(а) ISergeyN - 14.7.2009, 22:25
PM MAIL Skype   Вверх
Gordon
Дата 14.7.2009, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



Цитата(ller @  14.7.2009,  22:07 Найти цитируемый пост)
Если в методе умножения выделю память разыменую и верну, то объект сам не уничтожется в последствии.


оператор "Matrix & operator *(const Matrix & m1,const Matrix &m2)" возвращает ссылку на объект класса "Matrix", какую память ты собрался выделять, разыменовывать?



--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Gordon, 
Что то типа того
Код

    Matrix *result = new Matrix(m2.x,m1.y);
// тут делаем то что надо, умножаем матрицы...
    return *result; // Как мернуть значение, чтоб оно не терялось и не дублировалось

Но это утечки памяти
PM MAIL   Вверх
Gordon
Дата 14.7.2009, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



А зачем тебе создавать объект динамически? Чем тябя так: "Matrix result(m2.x,m1.y);", не устраивает?

p.s. да и память еще нужно будет освободить, а указатель теряется в твоем случае...

Это сообщение отредактировал(а) Gordon - 14.7.2009, 22:30


--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Устраивает, просто на автомате поставил ссылку. А нужно по значению....  smile

Добавлено через 1 минуту и 1 секунду
Код

friend Matrix & operator *(const Matrix &m1,const Matrix &m2); 


Зря я это сделал smile

Добавлено через 2 минуты и 20 секунд
ISergeyN,
Спасибо за совет, это тоже вариант.
PM MAIL   Вверх
Gordon
Дата 14.7.2009, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



По значению? Это еще зачем? Лишнии копии создаваться будут!

Это сообщение отредактировал(а) Gordon - 14.7.2009, 22:40


--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Это почему? Деструктор должен будет все подчистить.
Или я не прав?

Добавлено через 2 минуты и 48 секунд
Локальный объект выдет из области видимости и вызовится деструктор, который подчистит память, а копия вернется. Только нужно будет написать копирующий конструктор, который будет копировать содержимое массива. А не просто указатель как по умолчанию
PM MAIL   Вверх
Gordon
Дата 14.7.2009, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



Цитата(ller @  14.7.2009,  23:45 Найти цитируемый пост)
Деструктор должен будет все подчистить


Подчистит! (если написать его правильно)
Цитата(ller @  14.7.2009,  23:45 Найти цитируемый пост)
Локальный объект выдет из области видимости и вызовится деструктор

елси писать так:
Код

Matrix result(m2.x,m1.y);

то деструктор "вызовется сам", когда переменная выйдет из области видимости.
А если создавать объект динамически:
Код

Matrix *result = new Matrix(m2.x,m1.y);

то нужно еще и освободить память самому!
Код

delete result;

тогда будет вызван деструктор, а потом освобождена память!

Только зачем нужны лишнии копии? Это затраты на вызов конструктора.

Это сообщение отредактировал(а) Gordon - 14.7.2009, 22:59


--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Вот и я о чем.
Код

Matrix  operator *(const Matrix & m1,const Matrix &m2)
{
    
    Matrix result(m2.x,m1.y);
// тут делаем то что надо, умножаем матрицы...
    return result; // возвращаем по значению
}


Нужно делать так. А вот если деструктор не чистит, то будут утечки. Но это выходит за рамки этой темы smile
У меня вроде чистит все.
PM MAIL   Вверх
Gordon
Дата 14.7.2009, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



Цитата(ller @  15.7.2009,  00:07 Найти цитируемый пост)
У меня вроде чистит все.


Ну это хорошо что чистит!  smile 
Только я не пойму, зачем нужно по значению передавать? (ну просто интересно  smile )

p.s. Можно как ISergeyN предложил, только сделать через шаблоны, чтобы задавать размер матрицы самому...

Код

template <class T, unsigned int T1, unsigned int T2> 
class TMatrix
{
    public:
        TMatrix() 
        {
            for(unsigned int i = 0; i < T1; i++)
                for(unsigned int j = 0; j < T2; j++)
                    data[i][j] = T();
        }
        T& operator () (unsigned int i, unsigned int j)
        {
            return data[i][j];
        }
    private:
        T data[T1][T2];
};


так и с динамическим выделением памяти париться не нужно


--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



С одной стороны да, но к примеру, как я узнаю размерность результата
m3=m1*m2....
Вернее я то его знаю, но отслеживать его будет очень неудобно... Нужно помнить какой размерности m1 и m2.
И потом так получается интереснее учиться smile
PM MAIL   Вверх
Gordon
Дата 14.7.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 6



Ну Вам виднее...
Еще недостатоки примера с шаблоном в том, что увеличивается размер объекта  класса матрицы, т.к. он содержит массив а не указатель и "TMatrix<int, 4, 4>" и "TMatrix<int, 4, 3>" вроде как разные типы, что может помешать, ИМХО...

Это сообщение отредактировал(а) Gordon - 14.7.2009, 23:35


--------------------

  
     
PM MAIL WWW   Вверх
ller
Дата 14.7.2009, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Цитата(Gordon @  14.7.2009,  23:18 Найти цитируемый пост)
Только я не пойму, зачем нужно по значению передавать? (ну просто интересно  smile )

Не передавать а возвращать. Если возвращать указатель, то нужно под объект создавать память и потом ее самому чистить, если возвращать по значению, то с объектом можно работать как с переменной, вышел объект из области видимости вызвался деструктор.

Код

   Matrix m1(3,3), m2(3,3); // инициализируем 2 матрицы
   Matrix m3;
 
   m3=m1*m2; 

Как тут создается временный объект (m1*m2) и он после копирования удаляется. Через указатели код будет путаней
Код

   Matrix m1(3,3), m2(3,3); // инициализируем 2 матрицы
   Matrix *m3;
 
   m3=m1*m2; 
   &m2=m1*(*m3);
  delete m3;
  delete &m2; // И получится ли так




Это сообщение отредактировал(а) ller - 14.7.2009, 23:40
PM MAIL   Вверх
xvr
Дата 15.7.2009, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Возвращать нужно по значению (не по ссылке). А что бы это не привело к многочисленным созданиям и удалениям объектов, класс нужно разделить на 2: собственно сама реализация (она будет скрыта от пользователя), и класс - представитель, которые будет содержать smart pointer (например boost::shared_ptr) на реализацию. Объекты этого класса можно будет свободно порождать, копировать и удалять в любом количестве, и это не приведет к массовым манипуляциям с заказами/удалениями массивов (как в оригинальном варианте)

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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