Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.10.2011, 15:26   #1
pifpafx
 
Аватар для pifpafx
 
Регистрация: 07.07.2011
Сообщений: 6
Лампочка Объекты разных классов в динамическом списке

Приветствую товарищи! Возникла проблема: никак не могу додуматься как реализовать хранение объектов разных классов в одном списке, с возможностью добавления, удаления и просмотра информации об объекте по номеру в списке... Думаю может как нибудь прикрутить STL? Во только разве там возможно создание векторных списков для объектов разных классов?...
Код:
#include <iostream> // подключаем стандартную библиотеку организации ввода-вывода
using namespace std; // используем стандартное пространство имён
// Абстрактный класс Фигура
class Figure
{
    // защищенные данные класса
protected:
    double Volume,Height; // переменные для хранения значений объёма и высоты фигуры
    //char name[10]; // переменная для хранения названия фигуры
    // общедоступные функции класса
public:
    void showdata() const
    {
        cout << "Volume = " << Volume << " Height = " << Height << endl;
    }
    void getdata()
    {
        cout << "Enter Height ";
        cin >> Height;
    }
    // конструктор базового класса 
  Figure() : Volume(0), Height(0) // инициализируем при создании объекта с помощью конструктора
  {   /*пустое тело*/  };          // значения высоты и объёма "по умолчанию" равными 0    
};
// Производный класс - Пирамида
class Pyramid : public Figure
{
private:
    float area; // переменная для хранения значения площади основания пирамиды
public:
    Pyramid() : Figure (),  area(0)  // инициализируем при создании объекта значений объёма и высоты
    {    /*пустое тело*/ }             // с помощью конструктора абстрактного класса , а также 
                                     // площади основания пирамиды "по умолчанию"
    void getdata ()
    {
        Figure::getdata();
        cout << "Enter Area ";
        cin >> area;
        Volume = (Height * area)/3;
    }
};
// Производный класс - Куб
class Cube : public Figure
{
public:
    Cube() : Figure()    // инициализация объекта класса Куб
    { /*пустое тело*/ }
    void getdata ()
    {
        Figure::getdata();
        Volume = pow(Height,3);
    }
};
// Производный класс - Прямоугольный параллелепипед
class Parall : public Figure
{
private:
    int b,c;  // описание переменных для хранения длины и ширины параллелепипеда
public:
    Parall() : Figure()    // инициализация объекта класса Прямоугольный параллелепипед
    { /*пустое тело*/ }
    void getdata ()
    {
        Figure::getdata();
        cout << "Enter Length ";
        cin >> b;
        cout << "Enter Width ";
        cin >> c;
        Volume = (Height * b * c);
    }
};
// Производный класс - Цилиндр
class Cylinder : public Figure
{
private:
    float radius;  // описание переменной для хранения радиуса основания цилиндра
public:
    Cylinder() : Figure()    // инициализация объекта класса Цилиндр
    { /*пустое тело*/ }
    void getdata ()
    {
        Figure::getdata();
        cout << "Enter Radius ";
        cin >> radius;
        Volume = 3.141592 * pow(radius,2) * Height;
    }
};
// --------------------------------- ФУНКЦИЯ MAIN --------------------------------------
int main()
{
    int choice;
    char choice2;
    Pyramid P;
    Cube cube1;
    Parall Pl;
    Cylinder Cy;
    cout << "What would you like to do?\n";
    do 
    {
        cout << "(1) Create a new Figure "        
             << "\n(2) View information about the figure "        
             << "\n(3) Delete the figure "
             << "\n(4) See list of all figures \n";
        cin >> choice;
        switch(choice)
        {
            case 1: cout << "What shape would you like to create?";
                    cout << "\nPyramid(1), Cube(2), Parallelepiped(3), Cylinder(4)\n";
                    cin >> choice;
                    switch(choice)
                    {
                    case 1: P.getdata(); P.showdata(); break;
                    case 2: cube1.getdata(); cube1.showdata(); break;
                    case 3: Pl.getdata(); Pl.showdata(); break;
                    case 4: Cy.getdata(); Cy.showdata(); break;
                    }
                    break;
            case 2:  break;
            case 3:  break;
            case 4:  break;
        }
        
        cout << "Do you want to do something else? (y/n)";
        cin >> choice2;
    }
    while (choice2 == 'y' || choice2 == 'Y');
    return 0;
}

Последний раз редактировалось Stilet; 27.10.2011 в 08:35.
pifpafx вне форума Ответить с цитированием
Старый 26.10.2011, 15:35   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Виртуальные функции и std::list<Figure*> спасут отца русской демократии.
Abstraction вне форума Ответить с цитированием
Старый 26.10.2011, 15:55   #3
pifpafx
 
Аватар для pifpafx
 
Регистрация: 07.07.2011
Сообщений: 6
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Виртуальные функции и std::list<Figure*> спасут отца русской демократии.
Спасибо!
То есть в Абстрактном классе задать все функции виртуальными, таким образом чтобы в момент инициализации объекта они определялись? А данные класса и функции каким образом пихаются туда? я не силён в виртуальных функциях ...
pifpafx вне форума Ответить с цитированием
Старый 26.10.2011, 16:10   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Если в базовом классе объявить метод как virtual, то при вызове его по указателю вызовется вариант, соответствующий типу объекта, а не указателя (динамический полиморфизм).
Код:
//Создаём указатель на "фигуру вообще"
Figure* pSomeFigure;
//Пишем в него адрес объекта класса-наследника
pSomeFigure = new Cube();
//Вызываем функцию базового класса через указатель
pSomeFigure->showdata();
//Если функция была объявлена как виртуальная - вызовется Cube::showdata()
//Иначе же вызовется базовый вариант Figure::showdata(), по типу указателя
И замечание по словарю: в C++ абстрактным называется класс, в котором объявлен хотя бы один чисто виртуальный метод (метод, не имеющий определения в базовом классе). Figure же - самый обычный класс. Если есть желание запретить создавать его объекты в постороннем коде, стоит пометить его конструктор как protected.
Abstraction вне форума Ответить с цитированием
Старый 26.10.2011, 17:29   #5
pifpafx
 
Аватар для pifpafx
 
Регистрация: 07.07.2011
Сообщений: 6
Хорошо

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Если в базовом классе объявить метод как virtual, то при вызове его по указателю вызовется вариант, соответствующий типу объекта, а не указателя (динамический полиморфизм).
Код:
//Создаём указатель на "фигуру вообще"
Figure* pSomeFigure;
//Пишем в него адрес объекта класса-наследника
pSomeFigure = new Cube();
//Вызываем функцию базового класса через указатель
pSomeFigure->showdata();
//Если функция была объявлена как виртуальная - вызовется Cube::showdata()
//Иначе же вызовется базовый вариант Figure::showdata(), по типу указателя
И замечание по словарю: в C++ абстрактным называется класс, в котором объявлен хотя бы один чисто виртуальный метод (метод, не имеющий определения в базовом классе). Figure же - самый обычный класс. Если есть желание запретить создавать его объекты в постороннем коде, стоит пометить его конструктор как protected.
Спасибо огромное - пойду "курочить" код
pifpafx вне форума Ответить с цитированием
Старый 26.10.2011, 17:40   #6
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение

И замечание по словарю: в C++ абстрактным называется класс, в котором объявлен хотя бы один чисто виртуальный метод (метод, не имеющий определения в базовом классе). Figure же - самый обычный класс. Если есть желание запретить создавать его объекты в постороннем коде, стоит пометить его конструктор как protected.
На самом деле чисто виртуальный метод может иметь определение в базовом классе! Например, чисто виртуальный деструктор обязан иметь определение в базовом классе.Так что ваше определение чисто виртуальной функции не корректно.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 26.10.2011, 17:44   #7
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Сообщение от Сыроежка Посмотреть сообщение
На самом деле чисто виртуальный метод может иметь определение в базовом классе! Например, чисто виртуальный деструктор обязан иметь определение в базовом классе.Так что ваше определение чисто виртуальной функции не корректно.
Это как? То есть, может быть что-то в этом духе?
Код:
void Draw(Device*)const=0{cerr << "What the?..";}
Странно... а смысл?
Abstraction вне форума Ответить с цитированием
Старый 26.10.2011, 17:45   #8
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от pifpafx Посмотреть сообщение
Спасибо огромное - пойду "курочить" код
Не забудьте деструктор базового класса объявить виртуальным. Фактически, вам достаточно сделать деструктор чисто виртуальным, чтобы ваш класс был абстрактным. Например,


Код:
class Figure
{
    // защищенные данные класса
protected:
    double Volume,Height; // переменные для хранения значений объёма и высоты фигуры
    //char name[10]; // переменная для хранения названия фигуры
    // общедоступные функции класса
public:
    virtual void showdata() const
    {
        cout << "Volume = " << Volume << " Height = " << Height << endl;
    }
    virtual void getdata()
    {
        cout << "Enter Height ";
        cin >> Height;
    }
    // конструктор базового класса 
  Figure() : Volume(0), Height(0) // инициализируем при создании объекта с помощью конструктора
  {   /*пустое тело*/  };          // значения высоты и объёма "по умолчанию" равными 0 
   virtual ~Figure() = 0;   
};

Figure::~Figure() {}
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 26.10.2011, 20:16   #9
pifpafx
 
Аватар для pifpafx
 
Регистрация: 07.07.2011
Сообщений: 6
Хорошо

Цитата:
Сообщение от Сыроежка Посмотреть сообщение
Не забудьте деструктор базового класса объявить виртуальным. Фактически, вам достаточно сделать деструктор чисто виртуальным, чтобы ваш класс был абстрактным.
Спасибо =Ъ
pifpafx вне форума Ответить с цитированием
Старый 26.10.2011, 20:27   #10
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
Это как? То есть, может быть что-то в этом духе?
Код:
void Draw(Device*)const=0{cerr << "What the?..";}
Странно... а смысл?
Ну, во-первых, я вам ужеуказал,что чисто виртуальный деструктор обязан иметь определение в базовом классе. Что касается других функций, то почему вы не допускаете, что функция базового класса может иметь общий код для всех производных классов, которые они должны выполнять? Тем самым исключается дублирование кода.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сборщик мусора в динамическом списке Homutova_Julia Помощь студентам 4 17.06.2011 19:09
Объекты классов, деструкторы, конструкторы GerNick Общие вопросы C/C++ 18 15.03.2011 08:30
Строки разных цветов в списке. AntiKaspersky Общие вопросы .NET 2 14.01.2011 12:42
Создание классов и использование объектов классов при написании программ в среде C++. Frozen inside Помощь студентам 0 16.04.2009 23:18