0

我正在尝试将各种不同类型的数据存储在数组或向量中。到目前为止,我通过使用一个基类来做到这一点,该基类将作为指向每个对象的指针存储在向量中,然后进行类型转换以获取数据。这对 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;
    }
};

希望这有点道理,这是我的测试代码:

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;
}

我可能在这里犯了一些巨大的错误,但感谢您花时间阅读到目前为止:) 感谢您提供任何帮助,以及建设性的批评!

4

2 回答 2

2

您正在初始化堆栈上的 TMenuProperty 对象,然后将其转换为 cpMenuProperty。cpMenuProperty 中永远不会为 void* 数据分配任何内存。TMenuProperty 和 cpMenuProperty 之间没有关系,只是它们派生自同一个类。这种设计永远行不通。

  • 摆脱所有的 void*。那是自找麻烦。
  • 不要使用 static_cast<> 除非你 100% 知道你在做什么。使用 dynamic_cast,它会告诉你转换无效(我猜你尝试过这个但后来又回到 static_cast 以强制代码至少编译:))
  • 为什么不一直使用 TMenuProperty 呢?这种方法应该奏效。
  • 对于其他方式来做你所追求的,看看 boost::variant 和 boost::any。
  • 如果你很勇敢并且真的知道你在做什么(没有冒犯,但我认为你没有资格这样做),并且如果你需要包装的数据类型在内存布局方面足够统一,你也许可以使您的代码使用适当的内存填充设置并以某种方式强制内存对齐。但是,无论多么不可能,我都想不出任何方案来找到这样做的理由。因此,从这篇文章中我可以看出,我只能建议删除 cpMenuProperty 并仅使用抽象基类/模板化派生类方法。
于 2012-12-31T14:50:55.657 回答
0
 #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;
  }

经典的例子,使用现代实践。

于 2012-12-31T14:45:32.913 回答