其他分享
首页 > 其他分享> > c – 使用受保护的析构函数删除对象

c – 使用受保护的析构函数删除对象

作者:互联网

我必须为类编写一个共享指针,并且它必须做的许多其他事情是确保它可以删除它指向的对象.

如何编写可与具有受保护的析构函数的对象一起使用的解决方案?

另外,如果对象是使用placement new创建的,我不应该在对象上调用delete,因为该空间可能仍在使用(删除调用甚至可以工作吗?).我怎样才能发现这种情况?

规范的相关部分:

void reset(); The smart pointer is set to point to the null pointer. The reference count for the currently pointed to object, if any, is decremented.

Sptr(); Constructs a smart pointer that points to the null pointer.

template <typename U>
Sptr(U *);
Constructs a smart pointer that points to the given object. The reference count is initialized to one.

Sptr(const Sptr &);
template <typename U> Sptr(const Sptr<U> &);

The reference count is incremented. If U * is not implicitly convertible to T *, this will result in a syntax error. Note that both the normal copy constructur and a member template copy constructor must be provided for proper operation.

调用代码的方式:

        Sptr<Derived> sp(new Derived);
        char *buf = (char *) ::operator new(sizeof(Sptr<Base1>));
        Sptr<Base1> &sp2 = *(new (buf) Sptr<Base1>());
        sp2 = sp;
        sp2 = sp2;
        sp.reset();
        sp2.reset();
        ::operator delete(buf);

Base1拥有一切保护.

解决方法:

与引用计数器一起存储指向将删除对象的函数的指针(‘删除’).您将在智能指针的模板化构造函数中实例化删除器,您知道派生类型.这是一个非常天真的伪代码:

template<class T> void DefaultDeleter(void *p) { delete static_cast<T*>(p); }

struct ref_counter {
    int refs;
    void *p;
    void (*d)(void *);
};

template<class T> class Sptr { 
    /* ... */
    template <typename U> Sptr(U *p)
    {
        _c = new ref_counter;
        _c->refs = 1;
        _c->p = static_cast<void*>(p);
        _c->d = &DefaultDeleter<U>;
        _p = p;
    }

    T *_p;
    ref_counter *_c;
};

当refs降至零时,调用(* _c-> d)(_ c-> p)来销毁指向的对象.

我当然假设Base的析构函数受到保护而Derived的析构函数是公共的,否则这个练习没有任何意义.

注意:这就是为什么std :: shared_ptr可以安全地与具有非虚析构函数的基类一起使用的原因.

标签:c,c11,shared-ptr
来源: https://codeday.me/bug/20190826/1725281.html