【问题标题】:Retrieve objects pointers of different type检索不同类型的对象指针
【发布时间】:2018-08-10 10:05:05
【问题描述】:

考虑一下我有一堆指向不同类的不同对象的指针

class1* obj1;
class2* obj2;
class3* obj3;

他们都有一个方法getArray(),它返回一个用于后期处理的向量。

如果所有这些指针都存储在某种列表中(比如一个 void 指针列表)

当我迭代列表时,有没有办法确定可以使用哪种类型的指针转​​换?

我知道这可以通过类层次结构和从单个类派生上述类来解决。由于其中很多是遗留代码,可以完成上述提到的事情吗?

Folly dynamic 不允许我存储指针,这是尝试过的一件事

【问题讨论】:

  • 所有类都实现接口吗?如果是,您可以强制转换为接口的类型。如果它们没有以任何形式(接口、继承)链接,那就没那么容易了。
  • 你能修改有问题的列表吗?
  • 我们可以将void* 的列表替换为其他列表吗?

标签: c++ c++14 folly


【解决方案1】:

如果 getArray() 始终具有相同的签名(或足够相似以转换为相同的类型) - 您可以做的是为 duck-typed 遗留对象/类的 decorator 创建一个类层次结构。您可以使用非模板接口的模板派生类进行包装,而无需过多的打字工作。

类似的东西(更多的防御性编码,可能是指向遗留对象的智能指针等):

class IDecorator {
  public:
    virtual std::vector<ubyte> GetArray() = 0;
};

template<typename TLegacyType>
class TDecorator : public IDecorator {
   public:
     TDecorator(const TLegacyType *ip_legacy_object)
       : mp_legacy_object(ip_legacy_object) {}
     std::vector<ubyte> GetArray() override {
        return mp_legacy_object->GetArray();
     }

   private:
     const TLegacyType *mp_legacy_object;        
};

【讨论】:

  • 动态分配和放置新的 SOO 似乎对于这个问题来说都是多余的。使用 vtables 意味着其中之一。
  • 两个都是很好的答案,我不得不选择 Joris 的答案以适应现有的代码
【解决方案2】:
template<class R, class Op>
struct any_ptr {
  void* ptr=0;
  R(*f)( void* ) = 0;

  R operate() const { return f(ptr); }
  explicit operator bool() const { return ptr; }
  template<class T>
  T* as() const { return static_cast<T*>(ptr); }

  any_ptr(any_ptr const&)=default;
  any_ptr& operator=(any_ptr const&)=default;
  any_ptr()=default;

  template<class T>
  any_ptr(T* p_in):ptr(p_in),
    f( [](void* ptr)->R{ return Op{}( ptr ); } )
  {}
};

any_ptr 支持存储任何支持Op 的指针,其中Op 是返回R 的无状态函数对象类型。

struct get_array_t{
  template<class T>
  auto operator()(T* t)const{ return t->getArray(); }
};
using any_ptr_get_array = any_ptr< std::vector<int>, get_array_t >;

现在any_ptr_get_array 可以存储指向任何支持.getArray() 并返回vector&lt;int&gt; 的类型的指针。

拨打getArray

void test(any_ptr_get_array ptr){
  if(ptr){
    auto vec = ptr.operation();
  }
}

这种技术可以称为手动类型擦除,使用模板生成的 vtable。

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 2023-02-09
    • 2013-10-24
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多