【问题标题】:How to get pointer to new variable when using a move constructor使用移动构造函数时如何获取指向新变量的指针
【发布时间】:2020-04-09 16:02:55
【问题描述】:

所以我得到了这个代码:

//movable_ptr.hpp
//Michal Cermak

template<typename T> class movable_ptr;

template<typename T> class enable_movable_ptr {
public:
    //default constructor
    enable_movable_ptr() {};

    //move constructor and assignment
    enable_movable_ptr(enable_movable_ptr<T>&& p) {
        first_ = p.getFirst();
        p.retarget_to(this);
    };
    enable_movable_ptr<T>& operator=(enable_movable_ptr<T>&& p) {
        if (this != &p)
        {
            first_ = p.getFirst();
            p.retarget_to(this);
            delete &p;
        }
        return *this;
    };

    //retargets all pointers in the linked list to a new address
    void retarget_to(T* p)
    {
        if (first_ != nullptr)
        {
            auto current = first_;
            do
            {
                current->set(p);
                current = current->getNext();
            } while (current != first_);
        }
    };

    movable_ptr<T>* getFirst() { return first_; };
    void setFirst(movable_ptr<T>* p) { first_ = p; };
private:
    movable_ptr<T>* first_ = nullptr;
};

template<typename T> class movable_ptr {
public:
    //constructors and stuff...

    //access to variables
    T* get() {return ptr_; };
    void set(T* p) { ptr_ = p; };
    movable_ptr<T>* getNext() { return next_; };
    void setNext(movable_ptr<T>* p) { next_ = p; };
    movable_ptr<T>* getPrevious() {return prev_; };
    void setPrevious(movable_ptr<T>* p) { prev_ = p; };

private:
    T* ptr_ = nullptr;
    movable_ptr<T>* next_ = this;
    movable_ptr<T>* prev_ = this;
};

我的问题是我需要将T * 赋予retarget_to,但我在移动构造函数中使用retarget_to(this) 并在enable_movable_ptr 中赋值。通过enable_movable_ptr&lt;T&gt; * 而不仅仅是T *。问题是,我假设 T 继承自 enable_movable_ptr,它永远不会直接使用,只能通过从它继承的对象。例如:

class A : public enable_movable_ptr<A>
{
public:
    int val;

    A(int val) : val(val) {}
};

然后这样使用:

A x(42);
A y = move(x);

在这种情况下,this 将是enable_movable_ptr&lt;A&gt; *,但我需要一些可以给我A * 的东西。基本上我需要一个指向 = 运算符的左值的指针,同时在所述运算符的重载中。有没有办法做到这一点,还是我要求一些不可能的事情?

【问题讨论】:

    标签: c++ pointers lvalue move-constructor


    【解决方案1】:

    我还没有完全理解你的问题,因为不清楚你想用这个enable_movable_ptr 类实现什么。我认为你写operator= 的方式不正确。您正在尝试在指向 r 值的指针上显式调用 delete(可能首先在堆栈上分配,而且以后可能会通过其他一些机制被销毁)。

    我建议考虑operator= 的复制和交换方法,这样您就不必担心检查是否将对象分配给自身。签名将是enable_movable_ptr&lt;T&gt;&amp; operator=(enable_movable_ptr&lt;T&gt; other)(注意按值传递)。

    【讨论】:

    • enable_movable_ptr 基本上是任何从它继承的对象的外壳,允许它跟踪指向它的movable_ptr 指针的链接列表。将指针移动到链表的第一个movable_ptr 就可以了。问题是,我需要更改链接列表中所有movable_ptr 指向的位置,这将是operator= 分配内容的左值。另外,我不能真正更改签名,因为 move() 返回 A &amp;&amp;
    • 首先,您可以更改签名,因为您有一个移动构造函数。所以std::move会返回A &amp;&amp;,但是move构造函数可以隐式转换成A
    • 现在我对你想要的东西有了更好的理解:1)你可以做 static_cast(this); 2)您应该考虑在 enable_movable_ptr 中创建一个重要的析构函数,以将所有可移动_ptr 对象更新为 nullptr 之类的东西; 3)不清楚为什么你有一个循环列表而不是普通的单链表。
    • 做了静态演员,它有帮助,现在我还有其他问题,但这是我(希望)解决的问题。我确实有一个析构函数可以做到这一点,只是没有将它添加到代码 sn-p 中,因为我认为不需要它。该列表基本上是循环的,因为它是在本作业开始时提出的。我想我可以把它改成线性的,但我认为这对我没有任何帮助,所以我现在就让它保持原样。无论如何,谢谢你的帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2013-01-16
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多