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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическая типизация, как-то так 
:(
    Опции темы
jerdeks
Дата 16.9.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Допустим, у нас есть классы Фигура, Эллипс и Прямоугольник. Я хочу создать класс ЭллипсИлиПрямоугольник, которому ну например в конструктор передаются константа, определяющая, кем ему быть.
Есть мысль сделать так:

Код

class EllipseOrRectangle : Figure
{
public:
   EllipseOrRectangle(что-то, bool figure) {
      if (figure)
         Ellipse(что-то);
      else
         Rectangle(что-то);
   }
}


И даже работает, но потом мне надо определить, что же это за класс. Нет, можно конечно переменную завести, но может как-то красивее можно это сделать? Или может вообще то что я написал не правильно?
PM MAIL   Вверх
baldina
Дата 16.9.2011, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

думаю лучше решение типа такого:

Код

class Figure {...};

class Ellipse : public Figure {...}

class Rectangle : public Figure {...}

enum Figures { ELLIPSE, RECTANGLE };
Figure* makeFigure (Figures type)
{
   switch (type)
   {
        case ELLIPSE:
            retrurn new Ellipse;
        case RECTANGLE:
            retrurn new Rectangle;
   }
}


Добавлено @ 12:57
посмотри тут

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


Опытный
**


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

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





--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
jerdeks
Дата 16.9.2011, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(baldina)
использовать полиморфизм.
хотя в данном примере совершенно непонятно, что такое "эллипс или прямоугольник". чем они отличаются от других фигур?
и вообще, что бы предметно об этом рассуждать нужно знать что есть Figure, т.е. каков интерфейс.


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

ZVano

Цитата

Идентификация реального типа наследника происходит по коду в IShape->Code который указывается вручную при заполненни данными реального объекта.


Первая же мысль:
Цитата

Нет, можно конечно переменную завести, но может как-то красивее можно это сделать?

В той ветки перетирают из пустого в порожнее, а результат такой же.
PM MAIL   Вверх
newbee
Дата 16.9.2011, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


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

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



Цитата(ZVano @  16.9.2011,  13:59 Найти цитируемый пост)
Обсуждалось ранее
Пример 
Omg. Какой же смысл наследоваться, если потом в вызывающем коде приходится плясать со switch-ами? smile

Добавлено через 2 минуты и 19 секунд
jerdeks, используй решение baldina. Если где-то нужно будет определить, чем именно является фигура, воспользуйся dynamic_cast.


--------------------
You're face to face
With man who sold the world
PM   Вверх
ZVano
Дата 16.9.2011, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(jerdeks @  16.9.2011,  13:15 Найти цитируемый пост)
 может как-то красивее можно это сделать?

Не толко можно, а нужно. код
Нужно добавить виртуальный деструктор в базовый класс и станет доступен dynamic_cast. 


Код

#include <iostream>

struct IShape{
  int Id;
  int X; 
  int Y; 
  virtual ~IShape(){}; 
};

struct IShapeRectangle : public IShape{
  int Width;
  int Height;
};

struct IShapeSquare : public IShape{
  int SideLen;
};

void ShapeDraw(IShape * shape){
   std::cout << "SHAPE::Id = "<< shape->Id << "; X = " << shape->X << "; Y = " << shape->Y << std::endl;
   if(IShapeRectangle * shapeCustom = dynamic_cast<IShapeRectangle *>(shape)){
     std::cout << "Width = " << shapeCustom->Width << "; Height = " << shapeCustom->Height <<std::endl;
   }
   else if(IShapeSquare * shapeCustom = dynamic_cast<IShapeSquare *>(shape)){
     std::cout << "SideLen = " << shapeCustom->SideLen <<std::endl;
   } 
  else{
     std::cout << "Извини, чувак, не распознал тип фигуры " << std::endl;
  } 
}

int main(){
   IShapeRectangle shapeRectangle;
   shapeRectangle.Id = 1;
   shapeRectangle.X = 133;
   shapeRectangle.Y = 150;
   shapeRectangle.Width = 100;
   shapeRectangle.Height = 50;

   IShapeSquare shapeSquare;
   shapeSquare.Id = 2;
   shapeSquare.X = 77;
   shapeSquare.Y = 88;
   shapeSquare.SideLen = 200;
  
   ShapeDraw(&shapeRectangle);
   ShapeDraw(&shapeSquare);

   IShape shapeX;
   shapeX.Id = 3;
   shapeX.X = 999; 
   shapeX.Y = 999; 
   ShapeDraw(&shapeX); 
};



Цитата(jerdeks @  16.9.2011,  13:15 Найти цитируемый пост)
В той ветки перетирают из пустого в порожнее, а результат такой же.

Ответ там есть. 
Цитата(mes @  2.9.2011,  17:03 Найти цитируемый пост)
добавить в базу виртуальные методы (можно обойтись только виртуальным деструктором)..





--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
jerdeks
Дата 16.9.2011, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм.. вроде действительно надо как у baldin'a сделать. Но прийдется от родителя наследоваться. А может можно ещё как-нибудь? smile

ZVano, щас над твоим подумаю

Это сообщение отредактировал(а) jerdeks - 16.9.2011, 13:30
PM MAIL   Вверх
newbee
Дата 16.9.2011, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


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

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



Цитата(jerdeks @  16.9.2011,  14:27 Найти цитируемый пост)
Хм.. вроде действительно надо как у baldin'a сделать. Но прийдется от родителя наследоваться. А может можно ещё как-нибудь?
Еще можно в union засовывать разные фигуры, можно вместо наследования пользоваться комбинированием через template-ы (это что-то вроде стратегий в терминах паттернов или типа того, я не помню).


--------------------
You're face to face
With man who sold the world
PM   Вверх
mes
Дата 16.9.2011, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(jerdeks @  16.9.2011,  11:49 Найти цитируемый пост)
но потом мне надо определить, что же это за класс.

в такой абстрактной задаче есть только два варианта 
1. отразить типы на идентификатор 
2. отразить типы на интерфейс 
для обоих вариантов С++ имеет уже некоторые встроенные средства, но если их не хватает можно и похимичить.. 
а вот какая химия лучше всего подойдет, зависит от конкретики задачи.. 





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


Новичок



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

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



Ну я решил проблемку. Но вот все равно вот такой вопрос, уже теоретический - может ли в си++ объект из себя превратиться в кого-то другого?
PM MAIL   Вверх
ZVano
Дата 16.9.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(jerdeks @  16.9.2011,  16:20 Найти цитируемый пост)
... может ли в си++ объект из себя превратиться в кого-то другого?

Запросто. При помощи явного приведения типа. Но ничего хорошего из этого не получится  smile 



--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
jerdeks
Дата 16.9.2011, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я хочу чтобы объект сам себе превращал 8-)
Ну пофантазирую:

Код

void ClassA::func() {
   this->~ClassA();
   this = new ClassB;
}



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


Опытный
**


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

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



Цитата(jerdeks @  16.9.2011,  16:52 Найти цитируемый пост)
Я хочу чтобы объект сам себе превращал

ХЗ. Я еще недостаточно С++ знаю - от него можно ожидать чего угодно, такой уж он монстрище smile.
Посмотрим, что ГУРУ скажут.


--------------------
НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению.
Гуглим "Как правильно задавать вопросы"
PM MAIL Skype   Вверх
mes
Дата 16.9.2011, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(jerdeks @  16.9.2011,  15:52 Найти цитируемый пост)
Ну пофантазирую:

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

Это сообщение отредактировал(а) mes - 16.9.2011, 17:08


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


Эксперт
****


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

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



Цитата(jerdeks @  16.9.2011,  12:49 Найти цитируемый пост)
Есть мысль сделать так:

Ваш код:
Код

class EllipseOrRectangle : Figure
{
public:
   EllipseOrRectangle(что-то, bool figure) {
      if (figure)
         Ellipse(что-то);
      else
         Rectangle(что-то);
   }
}
делает совсем не то, что вы ожидаете. В строках 6 и 8 создаются временные объекты типов Ellipse и Rectangle, которые тут же и разрушаются. Они никоим образом никак не влияют на текущий экземпляр EllipseOrRectangle

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1918 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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