Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вернуть из функции указатель на объект 
V
    Опции темы
Нитонисе
Дата 27.2.2011, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть вот такой класс.
Код

class GLoads
{
  public:
    GLoad* operator[](int key)
    {
      Iter = Loads.find(key);
      return Iter->second;
    }

  protected:
    map<int,GLoad*> Loads;
    map<int,GLoad*>::iterator Iter;
};

Нужно используя оператор [] вернуть ссылку на объект GLoad, хранящийся в map. Моя реализация не работает, компилятор говорит, что возвращаемый объект является не указателем на GLoad, а самим объектом GLoad. Мне это не подходит, потому что GLoad - абстрактный класс, который не может иметь объектов.
PM MAIL   Вверх
mes
Дата 27.2.2011, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  27.2.2011,  13:30 Найти цитируемый пост)
 Моя реализация не работает, компилятор говорит, ч

реализация приведенная выше ? ошибки в ней нет.. 
сообщение компилятора в студию.. 

Цитата(Нитонисе @  27.2.2011,  13:30 Найти цитируемый пост)
вернуть ссылку

у Вас в коде возвращается указатель.. Вам нужна  там ссылка ?
тогда меняете на ссылку и добавляете разыменнование к секонду..

Добавлено через 1 минуту и 7 секунд
Цитата(Нитонисе @  27.2.2011,  13:30 Найти цитируемый пост)
    map<int,GLoad*>::iterator Iter

маловероятно, что Вам необходимо делать итератор членном.. лучше оставить локальной переменной.. 



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


Опытный
**


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

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



Цитата(mes @  27.2.2011,  14:48 Найти цитируемый пост)
сообщение компилятора в студию.. 

Вот пример использования
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  // Loads - объект класса GLoads
  int key = StrToInt(Edit1->Text);
  GLoad *l = Loads[key]; // ошибка
}

На комментированной строке компилятор выдает сообщение
Код

[C++ Error] Unit1.cpp(41): E2034 Cannot convert 'GLoads' to 'GLoad *'

Только сейчас обратил внимание, что оператор [] возвращает не GLoad, а вообще GLoads.


Цитата(mes @  27.2.2011,  14:48 Найти цитируемый пост)
маловероятно, что Вам необходимо делать итератор членном.. лучше оставить локальной переменной.. 

Объявил итератор членом из тех соображений, что его очень часто нужно будет использовать в функциях класса. Каждый раз создавать новый итератор может будет накладно?... не знаю
PM MAIL   Вверх
volatile
Дата 27.2.2011, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Покажите декларацию Loads. Очень похоже что это не объект класса GLoads, а массив объектов GLoads.

(кстати другой Loads в мемберах у вас уже есть. вы не путаетесь ?) 
PM MAIL   Вверх
mes
Дата 27.2.2011, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  27.2.2011,  14:24 Найти цитируемый пост)
На комментированной строке компилятор выдает сообщение

это строка не соответствует коду приведенному в первом посту..

Добавлено через 1 минуту и 58 секунд
Цитата(Нитонисе @  27.2.2011,  14:24 Найти цитируемый пост)
Объявил итератор членом из тех соображений, что его очень часто нужно будет использовать в функциях класса. Каждый раз создавать новый итератор может будет накладно?

не оптимизируйте раньше времени.. тем более если не знаете о расходах этого участка.. сделаете только хуже.. 



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


Опытный
**


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

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



Цитата(volatile @  27.2.2011,  15:49 Найти цитируемый пост)
Покажите декларацию Loads. Очень похоже что это не объект класса GLoads, а массив объектов GLoads.

Код

TForm1 *Form1;
GLoads *Loads;
GLoad *LinearLoad;
GLoad *PartLinearLoad;
GLoad *PointLoad;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Loads = new GLoads;
  // создаются указатели на наследников GLoad
  LinearLoad = new GLinearLoad(1,1.1,0.5);
  PartLinearLoad = new GPartLinearLoad(2,1.2,0.7,1000,1300);
  PointLoad = new GPointLoad(3,1.3,0.9,2500);
  // заполнение map объекта Loads указателями на GLoad
  Loads->AddLoad(1,LinearLoad);
  Loads->AddLoad(2,PartLinearLoad);
  Loads->AddLoad(3,PointLoad);  
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  delete Loads;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int key = StrToInt(Edit1->Text);
  GLoad *l = Loads[key];
}


Добавлено через 1 минуту и 51 секунду
Цитата(mes @  27.2.2011,  15:52 Найти цитируемый пост)
это строка не соответствует коду приведенному в первом посту.

Где ж она не соответсвует?

Цитата(mes @  27.2.2011,  15:52 Найти цитируемый пост)
не оптимизируйте раньше времени.. тем более если не знаете о расходах этого участка.. сделаете только хуже..

А чем это может быть плохо?
PM MAIL   Вверх
mes
Дата 27.2.2011, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



и зачем создавать свой тип (Gloads) ? не легче ли просто затайпдефить нужный стандартный контейнер ?

Добавлено через 55 секунд
чем меньше ненужных сущностей, тем меньше шансов у ошибок..


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


Опытный
**


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

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



Цитата(mes @  27.2.2011,  15:56 Найти цитируемый пост)
и зачем создавать свой тип (Gloads) ? не легче ли просто затайпдефить нужный стандартный контейнер ?

Нет. Ведь класс GLoads будет более функциональным... пока тестирую работу внутри него с мэпом. Да и синтаксис работы с мэпом трудночитаемый для использования его в главном коде.
PM MAIL   Вверх
mes
Дата 27.2.2011, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  27.2.2011,  14:54 Найти цитируемый пост)
А чем это может быть плохо? 

тем что
1. не зная, Вы не оптимизуруете, а пессимизируете код
2. закладываясь на оптимизацию, ухудшаете код, и создаете себе в дальнейшем лишние проблемы, как с развитием так и с поддержкой кода..
3. ставите палки в колеса компилятору, не давая  своей "оптимизацией" применить наиболее эффективный алгоритм..
4. ну и тратите время на то, что компилятор делает легко и с удовольствием
и т.д.

Добавлено через 5 минут и 40 секунд
Цитата(Нитонисе @  27.2.2011,  14:59 Найти цитируемый пост)
 Ведь класс GLoads будет более функциональным..

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

Цитата(Нитонисе @  27.2.2011,  14:59 Найти цитируемый пост)
 Да и синтаксис работы с мэпом трудночитаемый для использования его в главном коде. 

хм.. опять из крайности в крайность..у Вас получается, что если нет Gloads, то главный код становится трудночитаемым..

Добавлено через 7 минут и 53 секунды
Цитата(Нитонисе @  27.2.2011,  14:54 Найти цитируемый пост)
Где ж она не соответсвует?

тем что, Gloads не возвращает Gloads в оперaторе [], a значит ошибка в другом месте..

Добавлено через 8 минут и 43 секунды
а вот и причина ошибки:
Цитата(Нитонисе @  27.2.2011,  14:54 Найти цитируемый пост)
GLoads *Loads;

вы оператор[] применяете к указателю.. 




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


Опытный
**


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

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



Реализовал доступ к указателям на GLoad не через оператор [], а посредством простой функции
Код

GLoad* __fastcall GLoads::GetLoad(int key)
{
  Iter = Loads.find(key);
  return Iter->second;
}

И теперь этот код работает как надо
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int key = StrToInt(Edit1->Text);
  GLoad *l = Loads->GetLoad(key);
}

Интересно, почему ж не работает оператор? С ним запись более удобная.
PM MAIL   Вверх
mes
Дата 27.2.2011, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  27.2.2011,  15:27 Найти цитируемый пост)
почему ж не работает оператор? С ним запись более удобная. 

потому что надо вначале разыменовать указатель.. also :
Код

  GLoad *l = (*Loads)[key];
// или
 GLoad *l = Loads->operator[](key);
 



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


Опытный
**


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

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



Цитата(mes @  27.2.2011,  16:07 Найти цитируемый пост)
вы оператор[] применяете к указателю..

Точно. Запись получается не сильно красивей чем через функцию)

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


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


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

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



 а зачем контейнер по указателю хранить то ? 
да и это все :
Цитата(Нитонисе @  27.2.2011,  14:54 Найти цитируемый пост)
GLoads *Loads;
GLoad *LinearLoad;
GLoad *PartLinearLoad;
GLoad *PointLoad;

выглядит очень подозрительно.. не говоря о том, что являются глобальными переменными.. 




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


Опытный
**


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

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



Цитата(mes @  27.2.2011,  17:17 Найти цитируемый пост)
а зачем контейнер по указателю хранить то ?

Действительно) Нужды особой и нет. Разве что способ обращения к функциям через -> выглядит более удобным в свете наиболее частого применения.

Цитата(mes @  27.2.2011,  17:17 Найти цитируемый пост)
выглядит очень подозрительно.. не говоря о том, что являются глобальными переменными..

Это тестовое приложение для отладки классов. Хотя в реальном приложении эти объекты скорее всего тоже будут глобальными. Дело в том, что данные, которые в них содержатся, могут быть использованы в разное время работы пользователя с приложением. Всякий раз производить массу операций по созданию этих объектов будет накладным. Проще это сделать один раз, сохранить в глобальной переменной и затем использовать в любое время работы приложения. Есть способ лучше решать подобную задачу? Так я бы тоже был не против в локальные переменные это все закинуть, хотя бы из соображений экономии оперативной памяти.
PM MAIL   Вверх
mes
Дата 27.2.2011, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  27.2.2011,  16:35 Найти цитируемый пост)
 Есть способ лучше решать подобную задачу? 

однозначно..  три нижние вобще непонятно зачем нужны.. а Loads просто сделайте членом класса Form..
и динамическое создание ему вообще не нужно.. т.е. указатель не нужен.. 





--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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