0

好吧,我正在使用 Map 来存储任何类型的指针 (void*),并且它正在作用域对象中使用。这是范围类。

class Scope
{
  protected:
    Scope * parent;
    MyMap* map;
  public:
    virtual void setParent(Scope* p)=0;
    virtual Scope* getParent()=0;
    virtual void setOwner(void * owner)=0;
    virtual void * getOwner()=0;
    virtual Symbol * get(char* name)=0;
    virtual Symbol * get(char* name, Signature * sig)=0;
    MyMap* getMap()const;
 };

并且有 2 个类OrderedScopeDisorderedScope它们实现了Scope该类。

在我的项目中,我试图将所有数据存储为 void*,然后检索它们并将它们转换为适当的类型。当我将一个对象投射到它的类型上时,我发现一些数据丢失了。这是我得到的照片。 在此处输入图像描述

只是为了澄清Package类有范围。在那个范围内,我存储了Functions 类型的对象。所以当我想向它添加一个函数时,我应该先检索包对象,然后我可以使用该add函数插入新函数。

我不知道我是否正确地显示了问题,但我希望如此。感谢您的帮助。

4

1 回答 1

2

空指针是一种危险的机制,因为它们禁用了编译器对该指针的类型检查。因此,如果您犯了错误(例如将 void 指针转换为错误的类型),您不会收到编译时错误,您只会将问题视为运行时的错误行为,例如数据损坏。

所以,要回答这个问题:如果你想使用 void 指针并避免数据损坏,你必须非常非常确定当你将 void 指针转换为 (SomeType *) 时,void 指针指向的内存位置to 实际上包含一个有效的 (SomeType *) 而没有别的。特别是,您必须确保您的 void 指针指向的 (SomeType *) 仍然有效,并且在您创建 void 指针和您尝试强制转换的时间之间没有被删除/释放用它。在将 void 指针与多重继承结合使用时,您还需要注意潜在的问题,因为具有多个超类的类可以具有不同的“this”指针,具体取决于您将其视为哪个超类,并且强制转换为 void 指针不会自动为您存储正确的“this”指针(因为编译器可以'不知道你以后会对哪个“this”指针感兴趣)。

这一切都是可行的,但你的程序逻辑在所有情况下都必须 100% 正确。除了非常仔细地编写所有代码、研究代码以查找错误并彻底测试之外,没有捷径可走。valgrind 和 Purify 之类的代码检查器也有助于发现仅通过运行代码而症状并不总是很明显的错误。

也就是说,上面的评论者是对的——通常有更好/更安全的替代方法来使用 void-pointers。这些替代方案(例如模板和/或通用基类)不太容易出错,因为它们让编译器在编译时为您检测错误,而不是强迫您在运行时一一查找. 此外,考虑使用智能指针(例如 shared_ptr)而不是原始指针,因为这会将处理对象的生命周期卸载到编译器,它可以比手动代码更可靠和一致地处理该任务。

于 2013-05-20T14:59:03.363 回答