Как программно идентифицировать класс
От: Аноним  
Дата: 21.10.10 22:44
Оценка:
Написал для своей задачи библиотеку классов. Основной класс-предок и несколько от него потомков. От этих потомков создаются экземпляры и присутствуют в некотором списке, список каждый раз разный.

Каким образом правильно определять какому классу какой экземпляр принадлежит?

Раньше я обходился введением свойства "type" типа const int, в котором хранил номер класса, для каждого свой индивидуальный и не изменяющийся никогда, и чтобы сказать о классе конкретного экземпляра из вышеупомянутого списка, достаточно было это свойство прочитать. Но у Страуструпа говорится, что так делать не комильфо, а как надо рыцца особо некогда. Присоветуйте что-нибудь.
Re: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 21.10.10 22:51
Оценка:
Это я написал =) . Ну так вот он вам, мой вопрос.

Запишу только последние предложения покорректнее:

"...Но у Страуструпа говорится, что так делать не комильфо, а, чтобы узнать как надо, рыцца в книжках Страуструпа особо некогда. Присоветуйте что-нибудь."
Re: Как программно идентифицировать класс
От: Erop Россия  
Дата: 21.10.10 23:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Каким образом правильно определять какому классу какой экземпляр принадлежит?


А зачем это выяснять? Хорошо, когда пользователям не важно, какой конкретно там класс...

А>Раньше я обходился введением свойства "type" типа const int, в котором хранил номер класса, для каждого свой индивидуальный и не изменяющийся никогда, и чтобы сказать о классе конкретного экземпляра из вышеупомянутого списка, достаточно было это свойство прочитать. Но у Страуструпа говорится, что так делать не комильфо, а как надо рыцца особо некогда. Присоветуйте что-нибудь.


Ну нехорошо именно писать код так, что клиентскому коду надо знать тип наследника.
Но тип наследника можно узнавать многими способами.
1) при помощи dynamic_cast
2) так, как сделано у тебя
3) В каждом классе иметь статическое поле с описанием, а адрес самого поля использовать, как ID типа
4) Обычно такого рода классы и списки производятся какой-то фабрикой. У фабрики есть шаблон, по которому она создаёт тот или иной экземпляр. Вот экземпляр этого шаблон и можно использовать, как ID...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как программно идентифицировать класс
От: swingus  
Дата: 22.10.10 01:41
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Написал для своей задачи библиотеку классов. Основной класс-предок и несколько от него потомков. От этих потомков создаются экземпляры и присутствуют в некотором списке, список каждый раз разный.


А>Каким образом правильно определять какому классу какой экземпляр принадлежит?


А>Раньше я обходился введением свойства "type" типа const int, в котором хранил номер класса, для каждого свой индивидуальный и не изменяющийся никогда, и чтобы сказать о классе конкретного экземпляра из вышеупомянутого списка, достаточно было это свойство прочитать. Но у Страуструпа говорится, что так делать не комильфо, а как надо рыцца особо некогда. Присоветуйте что-нибудь.


есть класс type_info и оператор typeid()
Re[2]: Как программно идентифицировать класс
От: Bell Россия  
Дата: 22.10.10 04:10
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>"...Но у Страуструпа говорится, что так делать не комильфо, а, чтобы узнать как надо, рыцца в книжках Страуструпа особо некогда. Присоветуйте что-нибудь."


Ты лучше расскажи — зачем тебе знать тип наследника?
Любите книгу — источник знаний (с) М.Горький
Re[3]: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 23.10.10 09:17
Оценка:
B>Ты лучше расскажи — зачем тебе знать тип наследника?

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

Уже подсказали, буду пробовать.
Re[4]: Как программно идентифицировать класс
От: wander  
Дата: 23.10.10 09:21
Оценка:
Здравствуйте, ursus_a, Вы писали:

B>>Ты лучше расскажи — зачем тебе знать тип наследника?


_>Не мне знать его нужно, а программе определять. Например, чтобы нужный фрейм с полями ввода свойств подставить в зависимости от типа текущего (выделенного указателем) объекта.


Можно использовать виртуальные функции для этого. RTTI в языке со статической типизацией это не всегда хорошо.
Re[2]: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 23.10.10 09:26
Оценка:
E>Ну нехорошо именно писать код так, что клиентскому коду надо знать тип наследника.
E>Но тип наследника можно узнавать многими способами.
E>1) при помощи dynamic_cast
E>2) так, как сделано у тебя
E>3) В каждом классе иметь статическое поле с описанием, а адрес самого поля использовать, как ID типа
E>4) Обычно такого рода классы и списки производятся какой-то фабрикой. У фабрики есть шаблон, по которому она создаёт тот или иной экземпляр. Вот экземпляр этого шаблон и можно использовать, как ID...

ну, может и нехорошо, но если я буду писать про всю задачу, то стока букаф никто ни асилит. А за советы спасибо.

Если интересно, то вкратце. Есть кучка (список) соединенных четырехполюсников, около 15, каждый своего типа, типов примерно пять. У каждого типа свой набор свойств. Эти свойства надо вводить в экранных формах. На экране отображается список ЧП и набор свойств одного из них. Мне надо сделать так, что когда я выбираю конкретный ЧП из списка курсором,определялся тип объекта, и в соответствии с ним выдавалась форма для ввода свойств.

Пока писал, сообразил, как это можно сделать еще, но сначала таки-сделаю по своему.
Re: Как программно идентифицировать класс
От: minorlogic Украина  
Дата: 23.10.10 09:30
Оценка:
Надо просто не нарушать привило подстановки Лисков.

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

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

типа
derived_class* query_some_derived_class(base_class& bc); // return null if not derived

такой себе врапер аналогичный dynamic_cast
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Как программно идентифицировать класс
От: wander  
Дата: 23.10.10 09:37
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>Если интересно, то вкратце. Есть кучка (список) соединенных четырехполюсников, около 15, каждый своего типа, типов примерно пять. У каждого типа свой набор свойств. Эти свойства надо вводить в экранных формах. На экране отображается список ЧП и набор свойств одного из них. Мне надо сделать так, что когда я выбираю конкретный ЧП из списка курсором,определялся тип объекта, и в соответствии с ним выдавалась форма для ввода свойств.


_>Пока писал, сообразил, как это можно сделать еще, но сначала таки-сделаю по своему.


Псевдокод:
class BaseQuadripole
{
public:
    virtual void printInfo(InfoPrinter &) const = 0;

    virtual ~BaseQuadripole() {}
};

class QuadripoleType1
    : public BaseQuadripole
{
public:
    void printInfo(InfoPrinter & ip) const
    {
        ip << option1 << option2;
    }
private:
    // свойства
    // option1, option2
};

class QuadripoleType2
    : public BaseQuadripole
{
public:
    void printInfo(InfoPrinter & ip) const
    {
        ip << option1 << option2 << option3;
    }
private:
    // свойства
    // option1, option2, option3
};

int main()
{
    InfoPrinter pr;

    BaseQuadripole * qp = getPointerFromCursor();

    qp->printInfo(pr);
}
Re[3]: Как программно идентифицировать класс
От: neFormal Россия  
Дата: 23.10.10 09:40
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>Если интересно, то вкратце. Есть кучка (список) соединенных четырехполюсников, около 15, каждый своего типа, типов примерно пять. У каждого типа свой набор свойств. Эти свойства надо вводить в экранных формах. На экране отображается список ЧП и набор свойств одного из них. Мне надо сделать так, что когда я выбираю конкретный ЧП из списка курсором,определялся тип объекта, и в соответствии с ним выдавалась форма для ввода свойств.


может ЧП при создании рассказать, какая форма ему нужна?.
но вообще id типа не означает id класса, это у тебя так сложилось.. частный случай.. классов может быть больше для одного и того же типа.. поэтому я бы, наверное, оставил type_id..
...coding for chaos...
Re[3]: Как программно идентифицировать класс
От: Alexey F  
Дата: 23.10.10 10:34
Оценка: 1 (1)
Здравствуйте, ursus_a, Вы писали:

_>Если интересно, то вкратце. Есть кучка (список) соединенных четырехполюсников, около 15, каждый своего типа, типов примерно пять. У каждого типа свой набор свойств. Эти свойства надо вводить в экранных формах. На экране отображается список ЧП и набор свойств одного из них. Мне надо сделать так, что когда я выбираю конкретный ЧП из списка курсором,определялся тип объекта, и в соответствии с ним выдавалась форма для ввода свойств.


Выше ответили — здесь
Автор: wander
Дата: 23.10.10
, но если не хочется смешивать представление класса и сам класс, можно разделить на несколько классов:
// Отображатель полей ввода на форме (предопределение):
class FormProperties;

// Базовый класс для четырёхполюсников:
template<class T>
class BaseQuadripole {
public:
    // Загрузка свойств на форму:
    void load ( FormProperties const& properties ) const;
    // Если нужно - сохранение свойств при закрытии формы:
    void save ( FormProperties& properties );

    // Определение двух верхних ф-ций - после определения класса FormProperties.
};


class SomeQuadripole : public BaseQuadripole<SomeQuadripole> {
public:
    // Конструкторы, методы доступа, свойства...
};


class AnotherQuadripole : public BaseQuadripole<AnotherQuadripole> {
public:
    // Конструкторы, методы доступа, свойства...
};


// Можно разбить на базовый и производные классы, если предполагается несколько отображений:
class FormProperties {
public:
    // Конструкторы и всё такое.

    void load ( SomeQuadripole const& quadripole ) const {
        // здесь создаём поля ввода для данного типа четырёхполюсника
    }

    void save ( SomeQuadripole& quadripole ) {
        // А здесь сохраняем из поля ввода новое состояние для четырёхполюсника данного типа
    }

    // Аналогично:
    void load ( AnotherQuadripole const& quadripole ) const { /* ... */ }
    void save ( AnotherQuadripole& quadripole ) { /* ... */ }
};


// Двойная диспетчеризация:
template<class T>
void BaseQuadripole<T>::load ( FormProperties const& properties ) const {
    properties.load ( static_cast<T const&> ( *this ) );
}


template<class T>
void BaseQuadripole<T>::save ( FormProperties& properties ) {
    properties.save ( static_cast<T&> ( *this ) );
}
Re[2]: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 23.10.10 11:38
Оценка:
M>Если необходимо достучаться до конкретного потомка, тогда архитектура кривовата.

Потомка... класса? Или экземпляра?
Re[3]: Как программно идентифицировать класс
От: Erop Россия  
Дата: 23.10.10 16:43
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>Пока писал, сообразил, как это можно сделать еще, но сначала таки-сделаю по своему.

Ну это стандартная же задача. Обычно идут по одному из двух путей.
Путь 1. У базы ЧП есть виртуальный метод ShowProperties. Соответсвенно оно всё и делает.
Путь 2. Если в программе интерфейс отделён от бизнес-логики, то можно, например, иметь в программе специальные структуры данных, назовём их шаблонами четырёхполюсников. Шаблон содержит в себе информацию о том, какого именно типа сам ЧП, какого типа вьюшка его свойств и т. д.
Ну и по этому шаблону всё и создаём, при нужде. При этом ЧП может хранить в себе указатель на создавший его шаблон.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как программно идентифицировать класс
От: minorlogic Украина  
Дата: 23.10.10 20:16
Оценка:
Здравствуйте, ursus_a, Вы писали:

M>>Если необходимо достучаться до конкретного потомка, тогда архитектура кривовата.


_>Потомка... класса? Или экземпляра?


Я не понял вас, на примере можете показать, что вы имели в виду ?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 23.10.10 20:31
Оценка:
Cпасибо всем огромное, особенно за RTTI и за потоки. Забыл одно важное уточнение: библиотека должна компилироваться "и в окопе, и в траншее", то есть и для ПК, и для сигнального процессора, поэтому многие удобные штуки, характерные для ПК тут не прокатывают.

В таком случае не зазорно и просто самому вручную ставить свойство класса-константу, которая будет обозначать тип класса, хватит и переменной типа int. А можно еще с каждого класса собирать какое-нибудь характерное только для него (для каждого экземпляра) число. Например, указатель на конструктор этого класса. и по этому указателю идентифицировать, к какому классу принадлежит экземпляр.

Вопрос не столько в работоспособности, сколько в корректности идеи: насколько это приемлемо?

Хотя проще, конечно, циферку поставить =).
Re[2]: Как программно идентифицировать класс
От: Erop Россия  
Дата: 23.10.10 21:55
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>Например, указатель на конструктор этого класса. и по этому указателю идентифицировать, к какому классу принадлежит экземпляр.


IMHO, тогда уж намного лучше заиметь статическое поле с описанием каких-то данных про каждый конкретный класс. Например его имя можно там хранить, список атрибутов, ещё что-нибудь.
Заполнять всё это можно макросом, кстати.

_>Вопрос не столько в работоспособности, сколько в корректности идеи: насколько это приемлемо?

_>Хотя проще, конечно, циферку поставить =).

У циферки есть та проблема, что расширять набор типов неудобно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как программно идентифицировать класс
От: minorlogic Украина  
Дата: 24.10.10 10:05
Оценка:
Здравствуйте, ursus_a, Вы писали:

M>>Если необходимо достучаться до конкретного потомка, тогда архитектура кривовата.


_>Потомка... класса? Или экземпляра?


Достучаться до экземпляра потомка через экземпляр предка. Речь идет о рантайме.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Как программно идентифицировать класс
От: Bell Россия  
Дата: 25.10.10 03:41
Оценка:
Здравствуйте, ursus_a, Вы писали:

_>... А можно еще с каждого класса собирать какое-нибудь характерное только для него (для каждого экземпляра) число. Например, указатель на конструктор этого класса.


На всякий случай:

12.1/1
Constructors do not have names.
...
12.1/12
...
The address of a constructor shall not be taken.


Т.е. нельзя получить адрес конструктора.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Как программно идентифицировать класс
От: ursus_a Россия  
Дата: 26.10.10 04:59
Оценка:
Да понял уж...

Спасибо всем. =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.