| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Вернуть объект класса |
| Автор: efpies 24.11.2010, 15:07 | ||
| Здравствуйте. Столкнулся с такой проблемой: нужно как-то вернуть объект класса. вот, что есть
При попытке вывода - Access violation, да и в значениях rows_ и cols_ мусор. Внутри Transpose всё выводит нормально, да и конструктор копирования вызывается. То ли значение возвращает Transpose? Как быть, если надо вернуть объект и присвоить его адрес указателю? |
| Автор: triclosan 24.11.2010, 15:18 | ||
| имхо как-то плохо выглядит. если так
вообще-то лучше избегать прямого использования указателей и динамической памяти тем более в методах-геттерах, ведь у вас же не системное ПО, а прикладное. |
| Автор: efpies 24.11.2010, 15:56 | ||
| Вопрос в удобстве: ведь проще объявить указатель в начале функции и потом его задействовать (хотя это плохо, говорят), чем объявить статичный объект и тут же присвоить. Может, я и ошибаюсь, конечно. Ваша конструкция не сработала, зато сработала вот такая:
Почему это так? Я разве не возвращаю Matrix&? |
| Автор: triclosan 24.11.2010, 16:06 |
| Matrix& Matrix::Transpose() возвращает объект по ссылке. В вашем коде получаете объект по ссылке, далее берете его адрес и пишите в указатель. |
| Автор: bsa 24.11.2010, 16:17 | ||
efpies, не надо возвращать таким образом. потому что совсем не очевидно, что после этого необходимо присвоить адрес результата указателю, а в конце работы сделать delete. лучше сделай так:
Кстати, а метод Erase у тебя rows_ и cols_ случаем не обнуляет? |
| Автор: WhKitten 24.11.2010, 16:19 | ||||||||||
Помоему Вы путает ссылки и указатели это разные вещи.
поэтому код:
Трактуется как: выполнить оператор присваивания для объекта Matrix по адресу d. Поскольку d неинициализированна, то это вызывает Access Violation. Мы пытаемся выполнить оператор присваивания для несуществующего объекта класса. Кстати, если бы Вы написали так:
то компилятор бы обнаружил вашу ошибку. Всегда старайтесь инициализировать переменные, как можно раньше. |
| Автор: efpies 24.11.2010, 16:52 |
Нет, он просто удаляет double** values и присваивает ему NULL А что присваивать *d в таком случае? Если &(c.Transpose()), то Access violation на выводе, но rows_ и cols_ в порядке. |
| Автор: xvr 24.11.2010, 17:40 | ||
Если вам нужно вернуть объект и присвоить его в переменную, то так и пишите:
|
| Автор: WhKitten 24.11.2010, 17:52 | ||||
Только тогда надо будет определить оператор присваивания, аналогичный копирующему конструктору, за тем исключением, что он должен ещё выполнять очистку старого значения:
Но мне кажется проблема уже в чём то другом. &(c.Transpose()) возвращает адрес переменной в куче, а если delete не вызывалось, то она должна быть проинициализирована, о чём и говорит, что rows_ и cols_ в порядке. Может во время выполнения d->Print() выполняется доступ к несуществующему индексу? |
| Автор: WhKitten 24.11.2010, 18:14 | ||||
И ещё вариант. Вместо:
использовать:
тогда отпадёт надобность и в операторе присваивания и в копирующем конструкторе. И с указателями путаницы будет меньше. |
| Автор: efpies 24.11.2010, 19:06 | ||||
Ну, возможно, стоит попробовать научиться понимать их смысл, не так ли? Операция & - взять адрес, * - взять по адресу? В то же время & - ссылка, а * - указатель? Нет?
Да и вообще говоря, перегруженное сложение не вызовется, если не возвращать Matrix&, ибо not implemented. На самом деле, они были не в порядке, это моя ошибка: они становились равными 0. Оператор присваивания перегружен. Другое дело, что он вообще не вызывается, а вместо него вызывается конструктор копирования. Да и нужен ли этот оператор теперь? Что-то из них, выходит, можно убрать. В итоге получается вот что: 1. Транспонирование проходит на "ура". 2. Копирование не работает. Копируется 0, вернее. Потому что вызывается деструктор. Не оттого ли, что в Transpose объект локален? Хотя это может быть бредом. До этого, видимо, пока рановато) |
| Автор: WhKitten 24.11.2010, 19:35 | ||||||
Только надо отличать, когда это & объявление ссылки, а когда взятие адреса.
|
| Автор: triclosan 24.11.2010, 19:45 |
Вы не правы, как раз в этом направлении стоит углублять изучение С++, а мрачных конструкций new - delete по возможности пока избегать, вы же не контроллеры программируете. Пусть вас не вводит в заблуждение, что во многих книгах по с++ для новичков new - delete рассматривается как полноценный инструмент, всему свое время. Для правильного и глубокого понимания std::* могу порекомендовать Николай Джосьютис, C++. Стандартная библиотека, Питер, 2004. |
| Автор: xvr 24.11.2010, 20:50 | ||
|