是否可以创建一个没有模板的简单智能指针基类?

时间:2012-01-08 15:56:16

标签: c++ templates memory-management smart-pointers reference-counting

我想知道是否可以在不使用模板的情况下创建智能指针基类?

我见过许多实现,但都使用了tempalates。 例如,在其他类派生自的基类中实现智能指针逻辑。

4 个答案:

答案 0 :(得分:2)

问题是指针成员的类。

在像C#这样的语言中,有可能,因为有一个“object”类,每个其他类派生一个类。在这种情况下你会失去类型安全。

然而,在C ++中,你没有这样的东西,它有两个选择:

  1. 使用 void * reinterpet_cast - 由于类型安全而非常难看,真的不安全。
  2. 为您的班级编写大量的重载 - 为每个班级。不可行,因为它不适用于新类。
  3. 因此,最好的方法是使用模板 顺便说一句, template 的想法非常好,以至于C#在某个版本之后开始使用它。

答案 1 :(得分:1)

如果您希望智能指针类仅充当特定数据类型资源的资源管理类,那么您不需要模板。

如果您打算编写一个通用资源管理器类,那么您需要一个模板类。

答案 2 :(得分:1)

使用此方法的问题是您无法添加方法。是的,如果需要,可以使用继承来创建智能指针,但结果会相当有限。在这种情况下,继承是最佳解决方案。动态多态性很少是最好的解决方案,但这是一个不同的,更大的讨论(请注意,我没有说过从不)。

答案 3 :(得分:1)

我不确定为什么

#include <iostream>

class void_scoped_ptr {
public:
  virtual ~void_scoped_ptr() = 0;
  void operator=(void_scoped_ptr const&) = delete;

  explicit operator bool() const { return ptr != 0; }

protected:
  void_scoped_ptr(void* p) : ptr(p) {};

  void* ptr;
};

void_scoped_ptr::~void_scoped_ptr() {}

#define MAKE_DERIVED_SCOPED_BASE(T, NAME, DELETE, DEREF)                    \
class NAME : void_scoped_ptr {                                              \
public:                                                                     \
  typedef T element_type;                                                   \
  typedef element_type* ptr_type;                                           \
  typedef element_type const* const_ptr_type;                               \
                                                                            \
  NAME(ptr_type p) : void_scoped_ptr(p) {}                                  \
  ~ NAME() { DELETE cast(); }                                               \
  void reset(ptr_type p) {                                                  \
    DELETE cast();                                                          \
    ptr = p;                                                                \
  }                                                                         \
                                                                            \
  DEREF                                                                     \
  element_type& operator*() { return *cast(); }                             \
  element_type const& operator*() const { return *cast(); }                 \
                                                                            \
protected:                                                                  \
  ptr_type cast() { return static_cast<ptr_type>(ptr); }                    \
  const_ptr_type cast() const { return static_cast<ptr_type>(ptr); }        \
}

#define MAKE_DERIVED_SCOPED_PTR(T)                                          \
  MAKE_DERIVED_SCOPED_BASE(T, T ## _scoped_ptr, delete,                     \
    ptr_type operator->() { return cast(); }                                \
    const_ptr_type operator->() const { return cast(); }                    \
  )
#define MAKE_DERIVED_SCOPED_ARRAY(T)                                        \
  MAKE_DERIVED_SCOPED_BASE(T, T ## _scoped_array, delete [],                \
    element_type& operator[](size_t i) { return cast()[i]; }                \
    element_type const& operator[](size_t i) const { return cast()[i]; }    \
  )

struct TestClass {
  TestClass() { std::cout << "construct\n"; }
  ~TestClass() { std::cout << "destruct\n"; }

  void f() { std::cout << "f()\n"; }
};

typedef MAKE_DERIVED_SCOPED_PTR(TestClass) test_ptr;
typedef MAKE_DERIVED_SCOPED_ARRAY(TestClass) test_array;

int main() {
  {
    test_ptr p(new TestClass);
    p->f();
  }

  {
    test_array a(new TestClass[3]);
    a[2].f();
  }
}