请教有关《C++ primer》中 smart pointer 问题
代码如下:
int *pa = new int(1);
int *pb = new int(2);
//这里p1的构造函数会new一个U_Ptr, ip=pa,use=1
HasPtr p1(i, 77);
//这里p2的构造函数会new第二个U_Ptr, ip=pa,use=1
HasPtr p2(i, 88);
//这里p3的构造函数会new第三个U_Ptr, ip=pb,use=1
HasPtr p3(j, 99);
//这里首先会将p3中的U_Ptr ++use
//然后将p2中的U_Ptr --use,此时use=0,故delete掉其ip,也就是delete了pa
//最后将p3中的U_Ptr赋值给p2中的U_Ptr
p2 = p3;
/*
* 问题在于,在p2中delete了pa之后p1怎么办呢? p1还要用到pa啊
*/
谢谢各位~
[解决办法]
你的这个程序写的很乱,按照你的注释,我的理解是:
在“
//这里p2的构造函数会new第二个U_Ptr, ip=pa,use=1
HasPtr p2(i, 88);
”
这一句执行时,由于ip也指向pa,则use应该自动增加为2;
所以在后面 将p2中的U_Ptr --use,此时use=1,还不会delete掉其ip,所以p1仍然指向pa。
[解决办法]
同意楼主,确实没有将use加到2
[解决办法]
#include <iostream>
class U_Ptr
{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p): ip(p), use(1) {}
~U_Ptr() {delete ip;}
};
class HasPtr
{
public:
HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i) {}
HasPtr(const HasPtr &orig): ptr(orig.ptr), val(orig.val) {++ptr->use;}
HasPtr& operator=(const HasPtr&);
~HasPtr()
{
if (--ptr->use == 0)
{
delete ptr;
}
}
void print(void)
{
std::cout << "ptr=" << ptr << " "
<< "ptr->use=" << ptr->use << " "
<< "*ptr->ip=" << *ptr->ip << " "
<< "val=" << val << std::endl;
}
private:
U_Ptr *ptr;
int val;
};
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
++rhs.ptr->use;
if (--ptr->use == 0)
{
delete ptr;
}
ptr = rhs.ptr;
val = rhs.val;
return *this;
}
int main(int argc, char **argv)
{
int *i = new int(1);
HasPtr p1(i, 77);
HasPtr p2(i, 88);
//这样子确实没有用到复制构造函数,而它那地方所实现的只能是复制构造函数。
//这样肯定会报错了
//主要是智能指针是在复制构造函数或者赋值构造函数的时候注意《c++primer》也应该是那地方说,而你所说的情况就和下面其实类似,跟复制无关
/*int *i = new int(1);
HasPtr p1(i, 77);
delete i;*/
//而你想达到的目的就是有一个指针指向我所在的数据我就use+1,但是这个不可能可以做到,因为我指向你为什么要告诉你呢呵呵,所以编程的时候注意就行
}
[解决办法]
我认为有几个地方有问题
刚开始p2的use是1,当你执行p2=p3的时候由于
if (--ptr->use == 0)
{
delete ptr;
}条件满足则delete ptr既然已经delete ptr了为什么还ptr = rhs.ptr;
我在我的电脑上试了一下你的代码,我认为是p2的ptr delete了两次,置于你说的问题我认为只要不出现浅拷贝问题每个对象都拥有独立的ip,又不是static变量不会公用同一个ip
的,这只是我的见解,别喷我,咱俩可以共同商量