2

我需要编写一个函数来检索和处理一些数据。可以通过多种方式分配此数据(在数据段上、在堆上、在共享内存段上等等):

T *data;
if( global ) data = &d;
if( heap )   data = new T [ size ];
if( shm )    data = (T*) shmat( id, 0, 0 );
// processing data ...

由于data可能是动态分配的,我认为处理它的最佳方法是使用一种unique_ptr或其他类型的智能指针。但是它并不总是动态分配的:我需要在运行时为 选择删除器unique_ptr,但这是不可能的。

我应该如何定义和处理data

4

5 回答 5

6

您可以使自定义删除器获取运行时值!

struct MyCustomDeleter
{
   MemoryType type;
   template <typename T>
   void operator()(T* value) const
   {
      switch (type)
      {
         case MemoryType::heap:
             delete[] value;
             break;
         case MemoryType::shm:
             unmap_from_shm(value);
             break;
         // etc.
      }
   }
};

...

std::unique_ptr<T, MyCustomDeleter> ptr (new T[size], 
                                         MyCustomDeleter{MemoryType::heap});
于 2012-03-02T15:11:26.953 回答
3

我不确定std::unique_ptr,但你可以使用std::shared_ptr. 它的自定义删除器不依赖于类模板参数。

于 2012-03-02T15:10:38.443 回答
3

除了 KennyTm 的好答案之外,另一种可能性是使用函数指针作为删除器,然后在运行时提供不同的函数:

typedef std::unique_ptr<T, void(*)(void*)> Ptr;
void delete_global(void*);
void delete_heap(void*);
// etc.

Ptr get(/* whatever */)
{
    if ( ... )
       return Ptr(data, delete_global);
    if (... )
       return Ptr(data, delete_heap);

    // etc.
}
于 2012-03-02T16:20:53.480 回答
1

将您自己的智能指针与您选择的删除器一起使用:

enum DataPointerType
{
    Stack,
    Dynamic,
    SharedMem,
    ...
};

template <class T>
class DataPointer
{
public:
    DataPointer(T* pointer, DataPointerType type)
        : _ptr(pointer), _type(type)
    { }

    ~DataPointer()
    {
        switch (type) {
        case Stack: break;
        case Dynamic: delete _ptr; _ptr = nullptr; break;
        ...
        }
    }

    T& operator*() { return *_ptr; }
    const T& operator*() const { return *ptr; }

    T* operator->() { return _ptr; }
    const T* operator->() const { return ptr; }

private:
   T* _ptr;
    DataPointerType _type;

    // Prevent copying and destruction, dangerous
    DataPointer(const DataPointer& other);
    DataPointer& operator=(const DataPointer& other);
};
于 2012-03-02T15:08:49.353 回答
1

如果您使用共享shared_ptr<>,您可以在运行时选择删除器。只要您不复制/...,shared_ptr它的行为就应该与unique_ptr.

于 2012-03-02T15:10:46.040 回答