在C ++中存储类型

时间:2010-04-01 17:04:52

标签: c++ casting types

是否可以将类型名称存储为C ++变量?例如,像这样:

type my_type = int; // or string, or Foo, or any other type
void* data = ...;
my_type* a = (my_type*) data;

我知道99.9%的时间有更好的方法来做你想做的事情而不需要使用无效指针,但我很好奇C ++是否允许这样的事情。

8 个答案:

答案 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);
}

http://www.boost.org/doc/libs/1_42_0/doc/html/any/s02.html

答案 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
}

More info available here

答案 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);
    }
};

这种设计避免了解对象类型的需要。

相关问题