c ++ Является ли класс производным от определенного класса?

Возможно ли то, что я пытаюсь достичь. Это проблема:

class Content{};

class Content1 : public Content{};
class Content1_1 : public Content1{};
class Content1_2 : public Content1{};

class Content2 : public Content{};
class Content2_1 : public Content2{};
class Content2_2 : public Content2{};

class Container{
public:
Content* c;
};

Можно ли определить, является ли указатель Container класс указывает на объект Content1 или объект класса, производного от Content1?

Благодарю.

РЕДАКТИРОВАТЬ:

Если я посмотрю тип указателя в container класс, это рассматривается как content типа, хотя это может быть на самом деле content1 или же content2 тип, так что dynamic_cast не работает.

class content{};
class content1 : public content{};
class content2 : public content{};

class container{
public:
content* c;
};

int main(void)
{
container* x = new container;
x->c = new content2;

if( dynamic_cast<content1*>((content1*)x->c) == NULL){
//This doesn't fail, eventhough 'content1' and 'content2' shouldn't be compatible.
//This means that every class, derived from 'content' will be treated as 'content1' when using dynamic_cast.
}

return 0;
}

2

Решение

Если ваши типы полиморфны (то есть если у них есть хотя бы один virtual функция), вы можете использовать dynamic_cast<>, Результат dynamic_cast<> будет нулевым указателем (т.е. nullptr для C ++ 11, NULL для C ++ 03) в случае, если указанный объект фактически не является экземпляром указанного класса или его производного класса:

Container cont;
Content1* pContent1 = dynamic_cast<Content1*>(cont.c);
if (pContent1 != nullptr)
{
// cont.c points to an instance of Content1
// or a class derived from Content1
}

Обычной практикой является сделать деструктор вашего базового класса виртуального, так что объекты класса, производного от вашего базового класса могут быть deleteчерез указатель базового класса (если деструктор не virtualпопытка сделать это приводит к неопределенному поведению):

class Content //Abstract.
{
public:
virtual ~Content() { }
//  ^^^^^^^
};
2

Другие решения

Да использовать dynamic_casthttp://www.cplusplus.com/doc/tutorial/typecasting/

Это даст вам RTTI — Информация о типе времени выполнения.

Content1 * p = dynamic_cast<Content1 *>(c);

если p не NULL, то c указывает на объект, который является Content1 или является производным от Content1.
Однако ваша классовая иерархия должна быть полиморфной. Так как ваш класс Content является абстрактным (я предполагаю, что у вас есть чисто виртуальная функция в Content), вся ваша иерархия автоматически становится полиморфной.

1

Если вам нужно знать точный тип времени исполнения полиморфного класса, вам следует переосмыслить свой дизайн. Обычно лучше либо хранить объекты разных типов в разных контейнерах (дополнительно, либо вместо одного центрального контейнера), либо добавлять виртуальную функцию к каждому из производных классов, которая выполняет действие, при котором вам придется различать типы.

В FAQ C ++ есть запись, которая может вам помочь: У меня есть гетерогенный список объектов, и мой код должен делать специфичные для класса вещи с объектами. Кажется, что это должно использовать динамическое связывание, но не может понять это. Что я должен делать?

1

Если вы хотите увидеть, если Content* указывает на объект класса, производного от Content2 класс просто бросил его dynamic_cast и посмотреть.

Это работает:

#include <iostream>
#include <typeinfo>

using namespace std;

class Content{public: virtual ~Content(){}};

class Content1 : public Content{public: virtual ~Content1(){}};
class Content1_1 : public Content1{public: virtual ~Content1_1(){}};
class Content1_2 : public Content1{public: virtual ~Content1_2(){}};

class Content2 : public Content{public: virtual ~Content2(){}};
class Content2_1 : public Content2{public: virtual ~Content2_1(){}};
class Content2_2 : public Content2{public: virtual ~Content2_2(){}};

class Container{
public:
Content* c;
};

int main()
{
Content* cnt=new Content2_1;
if(dynamic_cast<Content2_1*>(cnt))
cout << "True" << endl;
return 0;
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector