关于智能指针的问题

关于智能指针的问题

本文介绍了关于智能指针的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的程序中有以下代码结构

Lets say I have the following code structure in my program

class Base
{
public:
Base(){//dosomething}
~Base(){//dosomething} //Note: Destructor is not virtual
...
virtual void function() {//dosomething}
};

class Derived: public Base
{
public:
Derived(){//dosomething}
~Derived(){//dosomething}
...
virtual void function() {//dosomething}
};





现在我写了类似的代码





Now I write a code something like

void somefunction()
{
std::shared_ptr<Base> stdBasePtr(new Derived() );

//do something with the Smart Pointers
}





现在一些函数超出范围后,因为析构函数或Base不是虚拟的。我期待内存泄漏。

Q1。我的假设是否正确?

Q2。如果上述问题的答案是否定的。然后如何处理。

Q3。如果答案是肯定的。然后我可以在我的智能指针实现中编码来处理这种情况。



提前致谢



Now after some function goes out of scope, since the destructor or Base is not virtual. I am expecting a memory leak.
Q1. Is my assumption correct?
Q2. If the answer to question above is no. Then how is it handled.
Q3. If the answer is yes. Then what can I code in my implementation of smart pointer to handle such scenarios.

Thanks in advance

推荐答案

class Deleter
{
public:
    virtual ~Deleter() {}
};

template <typename Deletable>
class TDeleter : public Deleter
{
public:
    TDeleter(Deletable* p)
        : m_Ptr(p)
    {}
    ~TDeleter()
    {
        delete m_Ptr;
    }
private:
    Deletable* m_Ptr;
};


template <typename T>
class Ptr
{
public:
    template <typename U>
    Ptr(U* p)
    {
        m_Deleter = new TDeleter<U>(p);
        m_Ptr = p;
    }
    ~Ptr()
    {
        delete m_Deleter;
    }
    T* operator->()                      { return m_Ptr; }
    const T* operator->() const          { return m_Ptr; }
    T& operator*()                      { return *m_Ptr; }
    const T& operator*() const          { return *m_Ptr; }
private:
    Ptr(const Ptr&);
private:
    Deleter* m_Deleter;
    T* m_Ptr;
};


class C
{
public:
    C() { printf("%s\n", __FUNCTION__); }
    ~C() { printf("%s\n", __FUNCTION__); }
    void BaseMethod() { printf("%s\n", __FUNCTION__); }
};

class D : public C
{
public:
    D() { printf("%s\n", __FUNCTION__); }
    ~D() { printf("%s\n", __FUNCTION__); }
};

void TestPtr()
{
    Ptr<C> p(new D);
    p->BaseMethod();
}





我更喜欢侵入式共享指针。一个侵入式共享指针希望你的类自己处理它自己的引用计数,因此一个侵入式共享指针希望你的类有自己的AddRef / Release方法(或者你命名的任何方法)。因此,当侵入式共享指针获取对象的所有权时,它会调用其AddRef。当指针让对象消失时,它会调用它的释放方法。为了使这个工作,对象要么实现AddRef / Release本身,要么通常代替这个,你从已经实现AddRef / Release以及引用计数的基类派生你的对象,除此之外它还为你引入了一个虚拟析构函数,可以自动帮助你避免破坏虫子。这样一个侵入式共享指针可以很容易地实现,以便它很好地处理继承,自动upcast可以在没有问题的情况下在这些指针之间工作。另一个很好的功能可以是你在对象中使用的基类,你可以提供两个实现:一个用于单线程使用,另一个用于多线程使用,用于处理带有原子操作的引用计数(__sync_add_and_fetch,InterlockedXXX,.. 。)。



编辑:我通常只在我自己的代码库中使用以下指针:

- 侵入式共享指针(单/多线程)

- 侵入性弱指针

- 自动指针



注意一个对象可以是两个共享的目标/ weak指针,只要所有共享/弱指针引用来自同一个线程,因为在多线程的情况下使用弱指针没有意义。



编辑:两者都是侵入性的和非侵入性指针有其优点。当引用的类不是你的时,非侵入性非常有用。侵入性的那些不太容易将原始c ++指针从一个引用转移到另一个引用。我的经验是,后者可能导致很难找到错误,并且与侵入性ptrs一起工作的系统不那么错。这当然只是我的观察/意见。



I like intrusive shared pointers much more. An intrusive shared pointer expects your class to handle its own refcounting by itself so an intrusive shared pointer expects your class to have its own AddRef/Release methods (or whatever you name them). So when an intrusive shared pointer takes ownership of your object then it calls its AddRef. When the pointer lets the object go aways then it calls its release method. For this to work the object either implements AddRef/Release itself, or usually instead of this you derive your object from a base class that already implements AddRef/Release along with refcounting and besides this it introduces a virtual destructor for you that automatically helps you to avoid destruction bugs. Such an intrusive shared pointer can easily be implemented so that it handles inheritance well, automatic upcast can work between such pointers without problems. Another nice feature can be in case of the base class you use in your objects that you can provide two implementations: one for single threaded use, and another one for multithreaded use that handles the reference count with atomic operations (__sync_add_and_fetch, InterlockedXXX, ...).

I usually use only the following pointers in my own codebase:
- Intrusive shared pointer (single/multithreaded)
- Intrusive weak pointer
- auto pointer

Note that an object can be the target of both shared/weak pointers as long as all the shared/weak pointer references come from the same thread because using weak pointers in case of multithreading has no point.

Both intrusive and nonintrusive pointers have their advantages. Nonintrusives are very useful when the referenced classes are not yours. Intrusive ones are less vulnerable to transferring "raw" c++ pointers from one reference into another. My experience is that the latter thing can cause very hard to find bugs and systems that work with intrusive ptrs are less buggy. This is of course just my observation/opinion.



这篇关于关于智能指针的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 03:14