首页 > 解决方案 > 退货不能转换

问题描述

我在下面有这段代码,我很难让它工作(movable_ptr<T>准确地说,是课堂上的操作员)。

//movable_ptr.hpp
//Michal Cermak

#ifndef MOVABLE_H
#define MOVABLE_H

template<typename T> class movable_ptr;

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

    //copy
    enable_movable_ptr(const enable_movable_ptr<T>&) {};
    enable_movable_ptr& operator=(const enable_movable_ptr<T>& p) {
        T* new_ptr = p.first_;
        movable_ptr<T>* new_first = p.first_;

        delete p;

        ptr_ = new_ptr;
        first_ = new_first;

        return this;
    };

    //move
    enable_movable_ptr(enable_movable_ptr<T>&& p) {};
    enable_movable_ptr& operator=(enable_movable_ptr<T>&& p) {};

    //destructor
    ~enable_movable_ptr() {delete ptr_; };

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

template<typename T> class movable_ptr {
public:
    //parameterless constructor
    movable_ptr() {};

    //constructor from T*
    movable_ptr(T* p) : ptr_(p) { add_to_tracked(this); };

    //copy
    movable_ptr(const enable_movable_ptr<T>&) {};
    movable_ptr& operator=(const enable_movable_ptr<T>& p) {};

    //move
    movable_ptr(enable_movable_ptr<T>&& p) {};
    movable_ptr& operator=(enable_movable_ptr<T>&& p) {};

    //destructor
    ~movable_ptr() {};

    //operators
    T& operator*() const { return ptr_; };
    T* operator->() const { return ptr_; };
    explicit operator bool() const noexcept { return ptr_ != nullptr; };
    bool operator!() const { return ptr_ == nullptr; };
    bool operator==(const movable_ptr<T>& p) const { return p.get() == ptr_; };
    bool operator!=(const movable_ptr<T>& p) const { return p.get() != ptr_; };

    //reset
    void reset() noexcept { ptr_, next_, prev_ = nullptr; };
    template<typename X> void reset(X* p) { remove_from_tracked(this); ptr_ = p; add_to_tracked(this); };

    //access to variables
    enable_movable_ptr<T>* get() {return ptr_; };
    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; };

    //get_movable
    movable_ptr<T>* get_movable(enable_movable_ptr<T>& p) {};
private:
    enable_movable_ptr<T>* ptr_ = nullptr;
    movable_ptr<T>* next_ = nullptr;
    movable_ptr<T>* prev_ = nullptr;
};

template<typename T> movable_ptr<T> get_movable(enable_movable_ptr<T>& p){
    return new movable_ptr<p>(p);
};

//removes movable_ptr from tracked pointers
template<typename T> void remove_from_tracked(movable_ptr<T>* p) {
    movable_ptr<T>* first = p->get()->getFirst();
    movable_ptr<T>* prev = p->get()->getFirst()->getPrevious();
    movable_ptr<T>* next = p->get()->getFirst()->getNext();

    if (first == p && next != nullptr)
    {
        p->get()->setFirst(next);
    }
    if (prev != next)
    {
        next->setPrevious(prev);
        prev->setNext(next);
    }
    else
    {
        next->setPrevious(nullptr);
        prev->setNext(nullptr);
    }
};

//adds movable_ptr to tracked pointers
template<typename T> void add_to_tracked(movable_ptr<T>* p) {
    movable_ptr<T>* first = p->get()->getFirst();
    movable_ptr<T>* prev = p->get()->getFirst()->getPrevious();

    if (first != nullptr)
    {
        if (prev != nullptr) {
            prev->setNext(p);
        }
        first->setPrevious(p);
    }
    p->get()->setFirst(p);
};

#endif
#include <memory>
#include <array>
#include "movable_ptr.hpp"

class MovableNode : public enable_movable_ptr<MovableNode>
{
public:
    static const int MAX_REFS = 4;
    using RefArray = std::array<movable_ptr<MovableNode>, MAX_REFS>;

    MovableNode() : _isValid(false), _value(0), _refs() {}
    MovableNode(int value) : _isValid(true), _value(value), _refs() {}

    bool isValid() const { return _isValid; }

    int value() const { checkValid(); return _value; }

    RefArray& refs() { checkValid(); return _refs; }
private:
    bool _isValid;
    int _value;
    RefArray _refs;

    void checkValid() const;
};

问题是,编译器无法将ptr_变量转换为正确的返回类型operator*operator==并且operator!=处于类似的情况,但这次是p.get()不能从 转换const movable_ptr<T>movable_ptr<T> &,因此可以正确比较。

错误:

错误 C2440 'return':无法从 'enable_movable_ptr<MovableNode> *const' 转换为 'T &'

错误 C2662 'enable_movable_ptr<A> *movable_ptr<T>::get(void)': 无法将 'this' 指针从 'const moving_ptr<T>' 转换为 'movable_ptr<T> &'

我很确定我只是遗漏了一个小细节,但我将如何解决这个问题?

实例化类的代码:

#include <iostream>
#include <memory>
#include <string>

#include "movable_ptr.hpp"

using namespace std;

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

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

void test_ptr_dereference() {
    A x(42);
    auto px = get_movable(x);

    TEST_ASSERT(&*px == &x);
    TEST_ASSERT(&px->val == &x.val);
}

int main(int argc, char* argv[]) {
    test_ptr_dereference();
}

标签: c++pointersreturnoperator-overloading

解决方案


推荐阅读