【问题标题】:Enforcing pointer to pointer type at compile time在编译时强制指针指向指针类型
【发布时间】:2013-04-14 23:53:07
【问题描述】:

我有一个对象层次结构的反序列化方案,其中大多数对象包含指向其他对象的指针,但不拥有它们。

我正在尝试实施一个两步流程,其中:

  1. 对象被创建,Register(Object* pObject)ed 到一个 ID,数据被读取。指针成员被序列化为唯一 ID,因此在读回它们时,我 RegisterResolver(int id, Object** ppMember)s。
  2. 处理解析器:查找 ID 并将正确的地址写入地址 *ppMember(注意取消引用)。

问题:

  • 我想强制只注册指向某个Base 类的对象或派生自某个Base 类的指针,但是Derived** 不能转换为Base**
  • 我想至少避免在使用void*(不是void**)时产生歧义,Derived** / Base** 可以同时转换为,但Derived* / Base*

在以下场景中:

struct A: public Serialized
{
  int blah;
};

struct B: public Serialized
{
  float fBlah;
  A*    pTarget;
};

B myB;

如果接口是RegisterResolver(int id, void* ppObject),则不能保证客户端代码不会通过myB.pTarget而不是&myB.pTarget

我可以做些什么来提高此解决方案的 [type-] 安全性和可读性?

(目标平台是 x86 和 ARM。)

【问题讨论】:

    标签: c++ pointers readability type-safety


    【解决方案1】:

    模板应该会有所帮助。怎么样

    template<typename T>
    void RegisterResolver(int id, T** ppObject, Base* extra = (T*)0);
    

    这允许任何类型的参数Derived** 存在从Derived*Base* 的隐式转换。

    【讨论】:

      【解决方案2】:

      由于最初的问题也与可读性有关,并且我想尽量减少界面上可能引起混淆的参数,因此我迭代了 Ben Voigt 的答案并最终得到了这个:

      template<typename T>
      void RegisterResolver(int id, T** ppObject)
      {
        // assert(ppObject != 0);
        Base* pBase(*ppObject); // not used
      
        // implementation
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        • 2011-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多