是否可以将类型名称存储为C ++变量?例如,像这样:
type my_type = int; // or string, or Foo, or any other type
void* data = ...;
my_type* a = (my_type*) data;
我知道99.9%的时间有更好的方法来做你想做的事情而不需要使用无效指针,但我很好奇C ++是否允许这样的事情。
答案 0 :(得分:22)
不,这在C ++中是不可能的。
RTTI typeid
运算符允许您在运行时获取有关类型的一些信息:您可以获取类型的名称并检查它是否等于另一种类型,但就是它。
答案 1 :(得分:14)
不是写的,但你可以做类似的事情......
class Type
{
public:
virtual ~Type(){}
virtual void* allocate()const=0;
virtual void* cast(void* obj)const=0;
};
template<typename T> class TypeImpl : public Type
{
public:
virtual void* allocate()const{ return new T; }
virtual void* cast(void* obj)const{ return static_cast<T*>(obj); }
};
// ...
Type* type = new TypeImpl<int>;
void* myint = type->allocate();
// ...
根据您需要的功能,可以扩展此类功能。
答案 2 :(得分:8)
你不能在C ++中这样做,但你可以使用boost任何库,然后测试它所拥有的类型。例如:
bool is_int(const boost::any & operand)
{
return operand.type() == typeid(int);
}
答案 3 :(得分:6)
不,您不能直接存储类型,但您可以存储类型的名称。
const char* str = typeid(int).name();
我想每当您计划使用该变量进行比较时,您可以将str
变量与类型的name()
进行比较。
const char* myType = typeid(int).name();
//....
//Some time later:
if(!strcmp(myType, typeid(int).name()))
{
//Do something
}
答案 4 :(得分:3)
是的,如果您自己编码。
enum Foo_Type{
AFOO,
B_AFOO,
C_AFOO,
RUN
};
struct MyFoo{
Foo_Type m_type;
Boost::shared_ptr<Foo> m_foo;
}
如下所述,我遗漏的是所有这些“foo”类型都必须与Foo相关。从本质上讲,Foo将是你的界面。
答案 5 :(得分:2)
今天编码时我遇到了类似的问题:
我需要将多态数据类型(此处命名为refobj)存储在实现它的具体类的调用函数上。我需要一个不明确转换变量的解决方案,因为我需要减少代码量。
我的解决方案(但我还没有测试过)看起来与之前的答案类似。实际上是一个很实验性的解决方案。它看起来像这样......
// interface to use in the function
class Type
{
public:
virtual void* getObj()const=0;
};
// here the static_cast with the "stored" type
template<typename T> class TypeImpl : public Type
{
public:
TypeImpl(T *obj) {myobj=obj;}
virtual void* getObj()const{ return static_cast<T*>(myobj); }
private:
T* myobj;
};
// here the type that will contain the polimorific type
// that I don't want to cast explicitly in my code
Type *refobj;
// here the "user code "
void userofTypes()
{
( refobj->getObj() ).c_str();
// getObj() should return a string type over which
// calling string concrete functions ...let's try!
}
void main()
{
refobj=new TypeImpl < string > ( new string("hello") );
userofTypes();
}
// it might seem absurd don't cast refobj explicitly, but of
// course there are situation in which it can be useful!
答案 6 :(得分:1)
类型不是C ++中的对象(例如,它们在Ruby中),因此您无法存储类型的实例。实际上,类型永远不会出现在执行代码中(RTTI只是额外的存储空间)。
根据您的示例,看起来您正在寻找typedef。
typedef int Number;
Number one = 1;
Number* best = (Number*) one;
请注意,typedef不是存储类型;它是别名的类型。
答案 7 :(得分:1)
更好的过程是拥有一个包含加载方法的公共基类,以及一个加载器的接口。这将允许程序的其他部分在不知道后代类的情况下一般加载数据:
struct Load_Interface;
struct Loader
{
virtual void visit(Load_Interface&) = 0;
}
struct Load_Interface
{
virtual void accept_loader(Loader& l)
{
l.visit(*this);
}
};
这种设计避免了解对象类型的需要。