C++ 在向量中存储各种类型

C++ 在向量中存储各种类型,c++,class,object,types,vector,C++,Class,Object,Types,Vector,我试图在数组或向量中存储各种不同类型的数据。到目前为止,我是通过使用一个基类来实现这一点的,该基类将存储在向量中,作为指向每个对象的指针,然后键入casting以获取数据。这对于int非常有效,但任何其他类型的数据都会引发访问冲突异常 如果我的解释不是很好,很抱歉,下面是我的代码和注释,希望能对您有所帮助: //Base class class MenuProperty { private: std::string Name; public: MenuProperty(std:

我试图在数组或向量中存储各种不同类型的数据。到目前为止,我是通过使用一个基类来实现这一点的,该基类将存储在向量中,作为指向每个对象的指针,然后键入casting以获取数据。这对于int非常有效,但任何其他类型的数据都会引发访问冲突异常

如果我的解释不是很好,很抱歉,下面是我的代码和注释,希望能对您有所帮助:

//Base class
class MenuProperty
{
private:
    std::string Name;

public:
    MenuProperty(std::string Name) : Name(Name) {};
    ~MenuProperty() {};

    std::string GetName();

};

//Typed class used to store data
template<class T>
class TMenuProperty : public MenuProperty
{
private:
    T Data;

public:
    TMenuProperty(std::string Name, T Data) : MenuProperty(Name), Data(Data) {};

    T GetData()
    {
       return this->Data;
    }
};

//Class with no type and data pointer to retrieve data
class cpMenuProperty : public MenuProperty
{
private:
    VOID* Data;

public:
    cpMenuProperty(std::string Name) : MenuProperty(Name) {};

    VOID* GetPointer()
    {
       return this->Data;
    }
};
//基类
阶级性
{
私人:
std::字符串名;
公众:
menuperty(std::string Name):Name(Name){};
~menuperty(){};
std::string GetName();
};
//用于存储数据的类型化类
模板
类TMenuProperty:公共菜单属性
{
私人:
T数据;
公众:
TMenuProperty(std::string Name,T Data):menuperty(Name),Data(Data){};
T GetData()
{
返回此->数据;
}
};
//类,但没有用于检索数据的类型和数据指针
类属性:公共菜单属性
{
私人:
作废*数据;
公众:
cpmenuperty(std::string Name):menuperty(Name){};
VOID*GetPointer()
{
返回此->数据;
}
};
希望这有点道理,下面是我的测试代码:

int main()
{
    TMenuProperty<double> fP("Test2", 33.7354); //Create instance of property

    MenuProperty* fMP = &fP;                    //Make a pointer to the object

    cpMenuProperty* Test;                       //Make a pointer to the retrieving
                                                //object

    std::vector<MenuProperty*>              Vec;
    std::vector<MenuProperty*>::iterator    it;

    Vec.push_back(fMP);                         

    it = Vec.begin();

    Test = static_cast<cpMenuProperty*>(*it);   //Cast the first object in the list 
                                                //list to the same type as the
                                                //retrieveing object


    double Data = *(double*)Test->GetPointer(); //Dereference and access, this is
                                                //where the exception is thrown

    std::cout << Data;



    int Ret;
    std::cin >> Ret;
}
intmain()
{
TMenuProperty fP(“Test2”,33.7354);//创建属性的实例
menuperty*fMP=&fP;//创建指向对象的指针
cpMenuProperty*Test;//创建一个指向
//反对
std::Vec;
std::vector::it迭代器;
矢量推回(fMP);
it=Vec.begin();
Test=static_cast(*it);//强制转换列表中的第一个对象
//列表的类型与
//检索对象
double Data=*(double*)Test->GetPointer();//取消引用和访问,这是
//抛出异常的位置
标准:cout>Ret;
}
我可能在这里犯了一些重大错误,但感谢您花时间阅读到目前为止:)感谢您提供的任何帮助,以及建设性的批评

#包括
 #include<iostream>
 #include<vector>
 #include<iterator>
 #include<memory>
 class base {
 public:
 virtual void foo(){
      std::cout << "in base" << std::endl;
  }
 };

 class derived : public base {
 public:
 virtual void foo(){
      std::cout << "in derived" << std::endl;
   }
 };

 int main()
 {
    std::vector<std::unique_ptr<base>> vec;
    vec.emplace_back(new derived);
    static_cast<derived*>(vec[0].get())->foo();
    return 0;
  }
#包括 #包括 #包括 阶级基础{ 公众: 虚拟void foo(){
std::cout您正在初始化堆栈上的TMenuProperty对象,然后将其强制转换为CmenuProperty。CmenuProperty中从来没有为void*数据分配任何内存。TMenuProperty和CmenuProperty之间没有关系,只是它们派生自同一类。这种设计永远不会起作用。

  • 摆脱所有的空虚,这是自找麻烦
  • 除非您100%知道自己在做什么,否则不要使用静态\u cast。使用动态\u cast,它会告诉您转换无效(我猜您尝试了此操作,但后来又使用静态\u cast强制代码至少编译:)
  • 为什么不一直使用TMenuProperty呢?这种方法应该是有效的
  • 要了解您所追求的其他方法,请查看boost::variant和boost::any
  • 如果你很勇敢,并且真的知道自己在做什么(无意冒犯,但我认为你没有资格这样做),如果您需要包装的数据类型在内存布局方面足够统一,那么您可以使用适当的内存填充设置并以某种方式强制内存对齐,使您的代码正常工作。但是,我无法想出任何方案,无论多么不可能找到这样做的理由。因此,从这篇文章中我可以看出,我只能建议删除cpMenuProperty,只使用抽象基类/模板化派生类方法

TMenuProperty fP(“Test2”,33.7354);将其更改为TMenuProperty*fP=新的TMenuProperty fP(“Test2”,33.7354);好吧,理论上,强制类型转换将允许void*指针落在存储在TMenuProperty中的数据的开头。感谢您花时间解释这种方法的缺点。我会重新考虑这一点。呃,仔细想想,我甚至不需要将这种方法用于CmenuProperty。很抱歉浪费您的时间他当时应该在发帖前多考虑一下。