以下实际编译并运行;
template <typename T>
class heap_ptr
{
public:
heap_ptr(T* p) : t(p) {}
heap_ptr(const heap_ptr&) = delete;
template<typename ... U> heap_ptr( U ... u )
{
t = new T(u...);
}
T* operator -> () { return t; }
// T& operator = (const T& o) { (*t)=o; return *t; }
operator T () { return *t; }
~heap_ptr() { delete t; }
private:
T* t;
};
struct A { int x,y; A(int x,int y):x(x),y(y){} };
void try_it()
{
heap_ptr<A> woop {8,11};
A a{5,3};
woop = a; // <- here
}
然而,标记的赋值将垃圾放入woop中。为什么要编译,和
为什么我会在窝里弄垃圾?
注意:如果我取消注释赋值运算符它按预期工作,那不是问题。
答案 0 :(得分:0)
问题是由于没有实现你的operator=
你依赖于默认的一个,它将复制临时对象的指针然后销毁它,一旦复制就会留下一个无效的指针完了。
这是不遵循三规则(C ++ 11中的五个)而导致的一组问题的实例。如果可以,您应该遵循rule of zero。
您正尝试重新实现智能指针。只需使用std::unique_ptr
并赢得编译,就像您期望的那样:
struct A { int x,y; A(int x,int y):x(x),y(y){} };
void try_it()
{
std::unique_ptr<A> woop{ new A(8, 11) };
A a{5,3};
woop = a;
}
答案 1 :(得分:0)
如果我取消注释赋值运算符它按预期工作,那就是 不是问题
这正是问题所在。默认情况下生成的复制赋值运算符将复制指针,而不是其后面的对象。然后销毁临时对象heap_ptr(a),删除指向的数据。