| imho.ws |
![]() |
|
|
|
# 1 |
|
Full Member
Регистрация: 25.11.2001
Адрес: Imho.ws
Сообщения: 941
![]() ![]() ![]() ![]() ![]() ![]() |
Гетерогенные объекты в С++
Привет!
Есть небольшой вопросик. Есть собрание объектов, класс Figure (виртуальный) из него выведен классы Line, Circle..etc c виртуальными ф-ями ... Нужно создать класс-контейнер содержащий все вожможнык круги, линии и тд. с возможностью добавления/удаления элементов. Есть идея использовать для этого вектор. class Container { public: // функции private: vector <Figure*> cont; }; что-то такое и вызывать его по Container a(new Line()); a.add(new Circle()); Вопрос! как вызывать конструктор? стандартный тут не пойдет как я понял. Нашел несколько примеров в нете, но там или вектор в main или используется array of Figure... (прям как в С) Буду очень благодарен за помощь ибо уже крыша едет...
__________________
Когда умираешь, да еще так долго и трудно, очень хочется хоть немного насолить живым, просто невозможно удержаться от искушения! М.Фрай |
|
|
|
|
# 3 |
|
Junior Member
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Даествительно мутно написано.
Зачем делать прослойку, если контейнер содержит только вектор? просто создаешь где надо vector <Figure*> contaniner; contaniner.push_back(new Line()); contaniner.push_back(new Circle()); ... contaniner.push_back(new Cube()); При этом абстаркатный класс Figure должен содержасть виртуальные методы, которые будут переопределны у потомков. И тогда конструкция типа contaniner[10]->Drow(); будет замечательно работать. Если есть какие-то специфичные методы, которые присущи только некоторым потомкам Figure, то можно заветси метод IsKindOf(), который будет говорить о том что это за потомок, после чего можно безболезненно приводить указтель к типу указателя на нужного потомка и работать.
__________________
Дураки не динозавры - они не вымрут... |
|
|
|
|
# 4 |
|
Full Member
Регистрация: 25.11.2001
Адрес: Imho.ws
Сообщения: 941
![]() ![]() ![]() ![]() ![]() ![]() |
Спасибо за ответы!
Сорри действительно странно получилось... Идея была сразу же объект и создавать, чтобы сонструктор и делал .push_back(new Cube()); но что-то там не сошлость (так и не понял почему), поэтому написал отдельный метод в классе. Figure содержит виртуальмые методы и все такое. Прослойка нужна для простоты, это все будет массово обрабатываться. Сейчас пытаюсь заставить програмку писать/читать это из файла. Господи... какая муть все это. В той книжке которую я читаю для этого предлагают создавать отдельный класс (который чуть ли не больше всего остального). Почему это нельзя просто сделать через if? писать в формате: фигура, коорд 1, коорд 2 if фигура = круг создать круг в контейнере if фигура = квадрат создать квадрат в контейнере и тд.
__________________
Когда умираешь, да еще так долго и трудно, очень хочется хоть немного насолить живым, просто невозможно удержаться от искушения! М.Фрай |
|
|
|
|
# 5 | |
|
Member
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245
![]() ![]() |
Цитата:
__________________
Best Regards |
|
|
|
|
|
# 6 |
|
Junior Member
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
согласен с alexey_ma
лино я поступил бы примерно так (очень примерно): Код:
//для Figure завел бы методы, в качестве параметров которым был бы,
//к примеру, дескриптор открытого файла.
virtual bool Read(int rFile);
virtual bool Write(int wFile);
//естественно для каждой фигуры переписал этот метод так чтобы
//она умела читать и писать инфу о себе в нужном виде.
//так же завел бы где-нибудь
Figure *CreateFigure(const figuretype &ft)
{
swtich(ft)
{
case circle:
return (Figure *)new Circle();
...
case cube:
return (Figure *)new Cube();
}
return (Figure *) new UnsupportedFigure(); //Ну или Exception выкидывать
}
//После чего в контейнере метор Read будет выглядеть примерно так.
{
int mFile;
//Открываем файл и читаем из него инфу всякую. потом доходим до
//самих фигур и читаем тип первой
while (!end)
{
Figure *newf=CreateFigure(readtype);
newf->Read(mFile);
m_storage.push_back(newf);
}
//Закрываем файл все прочитано
}
//Метод Write контейнера еще проще:
{
int mFile;
//Открываем файл и пришем в него инфу всякую
for (vector<Figure*>::const_iterator iter=m_storage.begin();
iter!=m_storage.end();iter++)
(*iter)->Write(mFile);
//Закрываем файл все записано
}
__________________
Дураки не динозавры - они не вымрут... |
|
|
|
|
# 7 | ||
|
Full Member
Регистрация: 25.11.2001
Адрес: Imho.ws
Сообщения: 941
![]() ![]() ![]() ![]() ![]() ![]() |
Цитата:
Цитата:
__________________
Когда умираешь, да еще так долго и трудно, очень хочется хоть немного насолить живым, просто невозможно удержаться от искушения! М.Фрай |
||
|
|
|
|
# 8 |
|
Junior Member
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Ну дескриптор, поток или CFile& разницы особой нет. Хотя поток пожадуй даже лучше.
Да с readtype это тот же самй if, только здесь чтение данных о самой фигуре ложится не на класс контейнера, на класс конкретной фигуры. ВСе что требуется в таком случае от контейнера, то вызывать методы фигур, даже не догадываясь о том как они читают/пишут и хранят данные.
__________________
Дураки не динозавры - они не вымрут... |
|
|