删除具有受保护析构函数的对象 [英] Delete an object with a protected destructor

查看:205
本文介绍了删除具有受保护析构函数的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to write a shared pointer for class, and among many other things that it has to do is make sure it can delete the object that it is pointing to.

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

How can I code a solution that will work with an object that has a protected destructor?

此外,如果对象是使用new放置创建的,则不应在对象上调用 delete ,因为该空间可能仍在使用中( delete 调用甚至可以工作吗?) 。如何检测到此类情况?

Additionally, if the object was created using placement new, I should not be calling delete on the the object, as that space may still be in use (will the delete call even work?). How can I detect such cases?

规范的相关位:


void reset(); 智能指针设置为指向空指针。

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();减少当前指向对象的引用计数。构造一个指向空指针的智能指针。

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

template< typename U>
Sptr(U *);
构造一个指向给定对象的智能指针。

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&);

模板< typename U> Sptr(const Sptr< U&);


引用计数增加。如果U *不能隐式转换为T *,则将导致语法错误。请注意,必须提供正常的复制构造函数和成员模板的复制构造函数才能正确操作。

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 具有受保护的所有内容。

Base1 has everything protected.

推荐答案

与引用计数器一起存储指向将删除该对象的函数的指针(删除程序)。您将在智能指针的模板化构造函数中实例化删除程序,在那里您知道派生类型。这是一个非常幼稚的伪代码:

Along with the reference counter store a pointer to the function that will delete the object (a 'deleter'). You will instantiate the deleter in the templated constructor of the smart pointer, there you know the derived type. Here is an extremely naive pseudocode:

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)破坏指向的对象。

When refs drops to zero, invoke (*_c->d)(_c->p) to destroy the pointed object.

I当然,假定 Base 的析构函数受保护,并且 Derived 的析构函数是公共的,否则该练习没有任何意义。 。

I of course assume that the destructor of Base is protected and the one of Derived is public, as otherwise the exercise makes no sense.

注意:这就是为什么 std :: shared_ptr 可以安全地与具有非虚拟析构函数的基类。

Note: This is why std::shared_ptr can be safely used with base classes with a non-virtual destructor.

这篇关于删除具有受保护析构函数的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆