我想知道是否可以在不使用模板的情况下创建智能指针基类?
我见过许多实现,但都使用了tempalates。 例如,在其他类派生自的基类中实现智能指针逻辑。
答案 0 :(得分:2)
问题是指针成员的类。
在像C#这样的语言中,有可能,因为有一个“object”类,每个其他类派生一个类。在这种情况下你会失去类型安全。
然而,在C ++中,你没有这样的东西,它有两个选择:
因此,最好的方法是使用模板 顺便说一句, 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();
}
}