2015-01-12 7 views
1

как я могу наложить void * на другой тип в C++, когда я не уверен, что такое другой тип. это образец моего кода:C++ cast void * когда не уверен, что такое тип

class A 
{ 
}; 
class B 
{ 
}; 
void main() 
{ 
    void * p; 
    if (rand() % 2) 
     p = new A(); 
    else 
     p = new B(); 

    A * a = NULL; 
    B * b = NULL; 
} 

Я хочу код, чтобы бросить указатель р на А *, если его тип A * и поместить ответ в а, еще отливать указатель р к В * если его тип B * и поместить ответ в b.

Я пробовал static_cast и регулярный подбор, но оба они каким-то образом не выполняли проверку выполнения, и даже если приведение не корректно, они не генерируют исключение.

+0

использование 'static_cast'. – 101010

+0

@ 101010 Это не помогает. –

+6

'void *' обычно не является решением ни для чего в современном C++. – crashmstr

ответ

1

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

Если вы хотите это сделать, вам необходимо повторить эту функцию. Для например: -

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

+0

Если мы собираемся принудительно наследовать, просто имея базовый класс 'class Object {public: virtual ~ Object() {};}', который все наследуемые классы позволяют использовать dynamic_cast (Предоставляя вам продолжать использовать виртуальные деструкторы) , – IdeaHat

+0

@IdeaHat Что вы подразумеваете под «Предоставляя вам продолжать использовать виртуальные деструкторы»? Достаточно виртуального в деструкторе базового класса. –

+0

спасибо большое ... –

1

Если вы можете изменить функции, чтобы не использовать недействительные указатели больше, вы можете использовать какое-то «безопасный пустой указатель» замена, по следующим направлениям:

struct A{}; 
struct B{}; 

struct AnyBase 
{ 
    virtual ~AnyBase() = 0; 
}; 
inline AnyBase::~AnyBase() {} 

template<class T> 
struct Any : public AnyBase 
{ 
    Any(T *p) : p(p) {} 
    T *p; 
}; 

void MaybeA(const AnyBase& p1) 
{ 
    const Any<A> *p2 = dynamic_cast<const Any<A>*>(&p1); 
    if (p2) 
    { 
     A *pa = p2->p; 
     cout << "Is an A\n"; 
    } 
    else 
    { 
     cout << "Is not A\n"; 
    } 
} 

int main() 
{ 
    A a; 
    B b; 
    MaybeA(Any<A>(&a)); 
    MaybeA(Any<B>(&b)); 
} 

подталкивание может иметь некоторые, возможно, опрятнее реализации этого. Хотя вам нужно будет изменить все свои функции, само изменение должно быть простым и даже обнаружить ошибки, о которых вы не знали!

Обратите внимание, что это решение не делает предположений о базовых типах. Им не нужно иметь виртуальные функции или их можно копировать.

0

Вы можете реализовать свой собственный RTTI. Добавьте общий базовый класс, который потребует, чтобы его подклассы сообщали о своих типах. Затем используйте static_cast для получения фактического типа.

#include <stdlib.h> 


enum class Type { A, B }; 

class Base { 
public: 
    virtual Type type() const = 0; 
    virtual ~Base() {} 
}; 

class A : public Base 
{ 
    Type type() const { return Type::A; } 
}; 
class B : public Base 
{ 
    Type type() const { return Type::B; } 
}; 

int main() 
{ 
    void * p; 
    if (rand() % 2) 
     p = new A(); 
    else 
     p = new B(); 

    Base *base = static_cast<Base*>(p); 

    A * a = NULL; 
    B * b = NULL; 

    if (base->type() == Type::A) { 
     a = static_cast<A*>(base); 
    } else if (base->type() == Type::B) { 
     b = static_cast<B*>(base); 
    } 
} 

Второй вариант, чтобы сохранить информацию о типе вне классов, например:

#include <stdlib.h> 

class A 
{ 
}; 
class B 
{ 
}; 
int main() 
{ 
    void * p; 
    bool is_a; 

    if (rand() % 2) { 
     p = new A(); 
     is_a = true; 
    } else { 
     p = new B(); 
     is_a = false; 
    } 

    A * a = NULL; 
    B * b = NULL; 

    if (is_a) { 
     a = static_cast<A*>(p); 
    } else { 
     b = static_cast<B*>(p); 
    } 
} 
+0

большое спасибо ... –

Смежные вопросы