我无法解释的行为

时间:2014-05-15 12:45:03

标签: c++

以下实际编译并运行;

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中。为什么要编译,和 为什么我会在窝里弄垃圾?

注意:如果我取消注释赋值运算符它按预期工作,那不是问题。

2 个答案:

答案 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;
}

Live demo

答案 1 :(得分:0)

  

如果我取消注释赋值运算符它按预期工作,那就是   不是问题

这正是问题所在。默认情况下生成的复制赋值运算符将复制指针,而不是其后面的对象。然后销毁临时对象heap_ptr(a),删除指向的数据。