Приветствую Вас ГостьПонедельник, 07.07.2025, 02:37

Light Midnight Inc.


Каталог статей

Главная » Статьи » Программирование » С/С++/MFC

RTTI. Поведение объектов.

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

Поведение RTTI(run time type information) включает в себя несколько гибких моментов которые вам могут помочь,но иногда и навредить. Все зависит от ситуации и корректности написания вашего кода.

Рассмотрим пример: Допустим у вас есть иерархия классов автомобилей и вам требуется выполнить над ними определенные изменения.

//Типичный базовый класс содержащий виртуальные функции.

class Car {
    virtual void see() {}
    virtual void setspeed() {}
}

Class Car может быть унаследован от какого нибудь стандартного класса. Например: SaveObj (сохранения объектов). CObject (MFC класс), наследуется базовым для переопределения нужных вам функций (функций записи данных).

Производные классы:

class Audi: public Car {
    public:
        short speed;
        void see(){};
        void setspeed(){};
}

class Bmw : public Car {

};

После этого получается:

Container<car>c; // Вам понадобится контейнер с доступом к произвольному элементу.

Audi audi1;
Bmw bmw1

c.push_back(audi1);
c.push_back(bmw1);
..                 // добавляем гараж автомобилей.

Как выбрать нужный нам автомобиль? Существует много способов:
1) Вложенным классом. СAuto position;
И написанием функции GetPosition() { return &position; } (она должна быть в базовом классе виртуальной).

int main() {
    CAuto myposition;
    for (I = с.begin(); I i!= с.end();i++) {
        Car *p = c->GetAt(i);
        if (mypositon == p->getPosition){
            // код
        }

Подобный метод был упомянут в книге Страуструпа:

        
void check(car *p) {
    if (p.typeid() == audi) {
        // do something;
    }

    if (p.typeid() == bmw) {
    }
}

Так называемая switch проверка. Лучший вариант ее использования это dynamic_cast<>;
(С++ .Специальное издание.Б.Страуструп.)

2) Методом определения объекта могут быть и встроеные функции системы. Например нажатие мышкой для графических объектов:

OnLButtonDown(point) { // нажатие левой кнопки мыши point –точка попадания
    for() // цикл по контейнеру
        Car *p = c->GetAt(I);                 // I – элемент итерации контейнера,
        if (p->GetPosition->PtInRegion(point)) { // если мы попали в позицию где стоит машина.
            // код
        }
}

3) Определение машины со временем:

CTime t;
Car *p;
if (p->GetTime == t.Now()) {
    // код
}

4) Может возникнуть ситуация когда один объект должен зависеть от других.

Установить чтобы одна машина двигалась за другой.

audi.speed = 100;
bmw.speed = 120;
audi.speed = bmw.getSpeed(); // getSpeed возвращает значения переменной Bmw.speed;

Сейчас audi.speed = 120;
Но если мы изменим скорость bmw,

bmw.setSpeed(130);

то audi.speed останется 120. А должно быть 130.
Для этого используйте int *speed.
И getSpeed() возращает адрес &speed;

audi.speed = getSpeed();

Замечание: При записи указателей в файл и выводе на экран могут возникнуть ошибки. С ними можно бороться при помощи memcpy или внешних/программных библиотек.

Так же для безопасности применяйте smart_ptr (зависит от поведения, например: клиент-сервер)

Категория: С/С++/MFC | Добавил: Cromartie (31.01.2013)
Просмотров: 391 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Оцените мой сайт
Всего ответов: 543
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Cheсking
Часы
Мини-чат
200
Друзья Сайта
  • Light Midnight - Ваша Еда
  • Light Midnight - Anim as life style
  • Поиск