我想知道是否可以在不使用模板的情况下创建智能指针基类?
我见过许多实现,但都使用模板。例如,在其他类派生的基类中实现智能指针逻辑。
我想知道是否可以在不使用模板的情况下创建智能指针基类?
我见过许多实现,但都使用模板。例如,在其他类派生的基类中实现智能指针逻辑。
问题是您的指针成员的类。
在像 C# 这样的语言中,这是可能的,因为有一个“对象”类,所有其他类都派生自该类。在这种情况下,您将失去类型安全性。
然而,在 C++ 中你没有这样的东西,这让你有 2 个选择:
因此,最好的方法是使用模板。
顺便说一句,模板的想法太好了,以至于 C# 在某个版本之后开始使用它。
如果您希望您的智能指针类仅充当特定数据类型资源的资源管理类,那么您不需要模板。
如果您打算编写一个通用资源管理器类,那么您确实需要一个模板类。
使用这种方法的问题是您无法添加方法。是的,如果需要,您可以使用继承来创建智能指针,但结果会相当有限。在这种情况下,继承并不是最好的解决方案。动态多态性很少是最好的解决方案,但这是一个不同且更大的讨论(请注意,我没有说过它永远不会)。
我不知道为什么
#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();
}
}