使用移动构造函数时如何获取指向新变量的指针
How to get pointer to new variable when using a move constructor
所以我得到了这个代码:
//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
,但我在enable_movable_ptr
中的移动构造函数和赋值中使用了retarget_to(this)
。这通过了 enable_movable_ptr<T> *
而不是 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<A> *
,但我需要一些可以给我 A *
的东西。基本上我需要一个指向 =
运算符左值的指针,同时在所述运算符的重载中。有什么办法可以做到这一点,还是我要求的东西是不可能的?
我还没有完全理解你的问题,因为不清楚你想用这个 enable_movable_ptr
class 实现什么。我认为您 operator=
的写作方式有误。您正在尝试在指向 r 值的指针上显式调用 delete(它可能首先在堆栈上分配,而且可能稍后会通过其他机制销毁)。
我建议考虑 operator=
的复制和交换方法,这将使您不必担心检查是否将对象分配给自身。签名将是 enable_movable_ptr<T>& operator=(enable_movable_ptr<T> other)
(注意按值传递)。
所以我得到了这个代码:
//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
,但我在enable_movable_ptr
中的移动构造函数和赋值中使用了retarget_to(this)
。这通过了 enable_movable_ptr<T> *
而不是 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<A> *
,但我需要一些可以给我 A *
的东西。基本上我需要一个指向 =
运算符左值的指针,同时在所述运算符的重载中。有什么办法可以做到这一点,还是我要求的东西是不可能的?
我还没有完全理解你的问题,因为不清楚你想用这个 enable_movable_ptr
class 实现什么。我认为您 operator=
的写作方式有误。您正在尝试在指向 r 值的指针上显式调用 delete(它可能首先在堆栈上分配,而且可能稍后会通过其他机制销毁)。
我建议考虑 operator=
的复制和交换方法,这将使您不必担心检查是否将对象分配给自身。签名将是 enable_movable_ptr<T>& operator=(enable_movable_ptr<T> other)
(注意按值传递)。