Что мне нужно сделать, чтобы спросить, есть ли указатель на абстрактный класс в экземпляре дочернего класса? - PullRequest
0 голосов
/ 10 мая 2019

Мне нужна помощь, чтобы все понять правильно.

Я хочу проверить указатель на абстрактный класс, если это экземпляр определенного дочернего класса.

У меня есть один абстрактный класс "Кунде »и два дочерних класса« Фирменкунде »и« Приваткунде », которые наследуют методы Кунде.

Для поиска по "int knr" (номер клиента int) я использую в качестве возвращаемого типа указатель на "kunde".

Внутри класса базы данных я получаю "kdstatus" и использую

kunde * kd = new privatkunde(0);

, если статус PK или новый firmenkunde (0), если это FK.У абстрактного класса kunde нет атрибута, который я мог бы использовать для сохранения статуса.

Таким образом, я надеялся, что смогу спросить, будет ли возвращенный указатель экземпляром класса privatkunde или firmenkunde.Но я не нашел никакого способа сделать это.

 MessageBox::Show(marshal_as<String^>(typeid(kd).name())); 

Я спрашивал имя typeid, но это только возвращает "class kunde *" и это не то, что я хочу знать.

Есть ли способ обойти эту проблему?

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

Вы можете использовать typeid, как вы упомянули.Используя полиморфизм, вы можете написать:

kunde * kd = new privatkunde(0);
if(typeid(kd) == typeid(privatkunde))
{
    // This is a privatkunde objet
}

См. здесь , чтобы получить более подробное объяснение.

Проблема, с которой вы сталкиваетесь, заключается в том, что ваш класс kunde не является полиморфным,Как прокомментировал @George, посмотрите, как работают виртуальные методы.

Надеюсь, это поможет.

0 голосов
/ 10 мая 2019

Как правило, вы можете использовать dynamic_cast для этого.

Пример:

class Parent
{
public:
    virtual ~Parent();

    virtual void do_thing()= 0;
};

class Child1: public Parent
{
public:
    void do_thing() override
    {
        //...
    }
};

class Child2: public Parent
{
public:
    void do_thing() override
    {
        //...
    }
};

void use_parent(Parent* p)
{
    auto c1_ptr = dynamic_cast<Child1*>(p);
    if(c1_ptr != nullptr)
    {
        // p is a Child1

        do_thing_with_child1(c1_ptr);

    }
    auto c2_ptr = dynamic_cast<Child2*>(p);
    if(c2_ptr != nullptr)
    {
        // p is a Child2
        do_thing_with_child2(c2_ptr);
    }
}

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

Лучший способ структурировать что-то вроде этого - использовать концепцию «Говори, не спрашивай» при разработке объектно-ориентированногосистемы.Отличное описание этой концепции можно найти здесь .

...