使用移动构造函数时如何获取指向新变量的指针

Posted

技术标签:

【中文标题】使用移动构造函数时如何获取指向新变量的指针【英文标题】: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 * 的东西。基本上我需要一个指向 = 运算符的左值的指针,同时在所述运算符的重载中。有没有办法做到这一点,还是我要求一些不可能的事情?

【问题讨论】:

【参考方案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 中,因为我认为不需要它。该列表基本上是循环的,因为它是在本作业开始时提出的。我想我可以把它改成线性的,但我认为这对我没有任何帮助,所以我现在就让它保持原样。无论如何,谢谢你的帮助:)

以上是关于使用移动构造函数时如何获取指向新变量的指针的主要内容,如果未能解决你的问题,请参考以下文章

如何在构造函数中访问类变量以在不使用 C++ 中的 this 指针的情况下分配它们

c++中如何获取函数名,和获取到一个基类指针后,如何判断它里面保存的是那个子类类型对象?

在类中获取指向自身的指针

如何获取指向专门针对字符串的模板函数的指针?

qt如何获取主窗口的指针

如何从模板类型中获取指向模板化成员函数的指针?