【发布时间】:2018-01-13 19:06:39
【问题描述】:
// I developed my own shared pointer . I know it is not required to create
//ur own when already there is a tested one available . But this is purely
//for learning, understanding and thinking purpose . The below shared
//pointer works fine in most of the cases and not causing any memory leak
//either . But it is not working in case of STL's . Below is my shared
//pointer .
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
template <class T>
class SharedPointer
{
template<class U>
friend class SharedPointer;
T *p;
int *rc;
public:
SharedPointer():p(NULL),rc(NULL) {}
template <class U>
explicit SharedPointer(U *q)
{
p = static_cast<T *>(q);
rc = new int();
++*rc;
}
~SharedPointer()
{
if(rc != NULL && --*rc == 0)
{
delete p;
p = NULL;
delete rc;
rc = NULL;
}
}
T * operator -> () { return p; }
T & operator * () { return *p; }
template<class U>
explicit SharedPointer(const SharedPointer<U> &q)
{
if(q.p)
{
p = static_cast<U *>(q.get());
rc = q.rc;
++*rc;
}
}
template<class U>
SharedPointer<T> & operator = (const SharedPointer<U> &sp)
{
if(this->p != static_cast<T *>(const_cast<U *>(sp.get())))
{
if(p != NULL)
{
if(--*rc == 0)
{
delete p;
delete rc;
p = NULL;
rc = NULL;
}
}
if(sp.get())
{
p = static_cast<T *>(sp.get());
rc = sp.rc;
++*rc;
}
else
{
p = NULL;
rc = NULL;
}
}
return *this;
}
};
// And now below is the usage .
class A
{
int i;
public:
A(int pi):i(pi){ }
~A()
{
cout<<"Destructor Called for "<<i<<endl;
}
void show()
{
cout<<i<<endl;
}
int intake() { return i; }
};
struct A_Comp
{
bool operator()(const SharedPointer<A> &lhs, const SharedPointer<A> &rhs)
{
return lhs->intake() < rhs->intake();
}
};
int main()
{
set<SharedPointer<A>,A_Comp> myset;
A * a = new A(30);
myset.insert(SharedPointer<A>(a)); // Line X
set<SharedPointer<A> >::iterator itr;
for(itr = myset.begin(); itr != myset.end(); itr++)
{
(*itr)->show();
}
return 0;
}
输出:
调用 30 的析构函数
4151280
实际上发生的事情是,X 行(参见 cmets)正在执行,它正在调用显式 SharedPointer(U *q),这与预期的一样,但是当此构造函数完成时,将调用 SharedPointer 的析构函数正在删除该变量。因此,即将到来的第二行是垃圾值,在不同的执行中可能会有所不同。我的问题是为什么 ~SharedPointer 应该在 main function 的 return 语句之前执行时才被调用。虽然 ~SharedPointer 在 main 返回之前被调用,但我无法弄清楚为什么它第一次被调用。标准的 shared_ptr 没有这种行为。
我正在使用 -fpermissive 选项来避免与 const 相关的错误。
【问题讨论】:
-
你能把它减少到minimal reproducible example吗?
-
@R Sahu,我删除了额外的功能。谢谢。
-
@manni ,我使用了调试器,只有在 SharedPointer(U *p) 构造函数完成时才知道 ~SharedPointer 被调用。但无法弄清楚为什么该对象在 main 的 return 语句之前不会超出范围。
-
要使 shared_ptr 工作,您需要将指针保存到 shared_ptr 本身以外的对象上,如果 shared_ptr 拥有指针,您将遇到复制和赋值操作问题,其中一个shared_ptr(甚至是临时的)超出范围并被销毁,并带上指针。
标签: c++ stl set shared-ptr