Home > Software design >  How to improve my custom unique_ptr class? I want to realize that derived class can cast to base cla
How to improve my custom unique_ptr class? I want to realize that derived class can cast to base cla

Time:03-13

I realize a unique_ptr class by myself as below, and use it to manage another class:

namespace mcj {
template <typename CallbackT>
class unique_ptr {
 public:
  unique_ptr(CallbackT* ptr = nullptr) : ptr_(ptr) {
    std::cout << "unique_ptr normal constructor" << std::endl;
  }

  unique_ptr(unique_ptr<CallbackT>&& ptr) {
    if (ptr_) {
      delete ptr_;
      ptr_ = nullptr;
    }
    ptr_ = ptr.release();
    std::cout << "unique_ptr move constructor(unique_ptr<CallbackT>&& ptr)"
              << std::endl;
  }

  unique_ptr<CallbackT>& operator=(unique_ptr<CallbackT>&& ptr) {
    if (ptr_) {
      delete ptr_;
      ptr_ = nullptr;
    }
    ptr_ = ptr.release();
    std::cout << "unique_ptr move operation(=)" << std::endl;
    return *this;
  }

  unique_ptr(const unique_ptr<CallbackT>& other) = delete;
  unique_ptr<CallbackT>& operator=(const unique_ptr<CallbackT>& other) = delete;

  ~unique_ptr() {
    delete ptr_;
    ptr_ = nullptr;
  }

  CallbackT& operator*() { return *ptr_; }
  CallbackT* operator->() { return ptr_; }
  CallbackT* get() const { return ptr_; };

  CallbackT* release() {
    if (ptr_) {
      CallbackT* temp = ptr_;
      ptr_ = nullptr;
      return temp;
    }
    return ptr_;
  }

 private:
  CallbackT* ptr_;
};
}  // namespace mcj

I call mcj::unique_ptr like this, A is base base class and B is derived class:

mcj::unique_ptr<A> CastToBase() {
  return mcj::unique_ptr<B>(new B);
}
mcj::unique_ptr<A> h = CastToBase();

But an error occurs:

/Users/chaojie.mo/Documents/test/test/main.cpp:42:10: error: no viable conversion from returned value of type 'unique_ptr' to function return type 'unique_ptr' return mcj::unique_ptr(new B); ^~~~~~~~~~~~~~~~~~~~~~~~~ /Users/chaojie.mo/Documents/test/src/callback_utils.h:11:3: note: candidate constructor not viable: no known conversion from 'mcj::unique_ptr' to 'A ' for 1st argument unique_ptr(CallbackT ptr = nullptr) : ptr_(ptr) { ^ /Users/chaojie.mo/Documents/test/src/callback_utils.h:15:3: note: candidate constructor not viable: no known conversion from 'mcj::unique_ptr' to 'unique_ptr &&' for 1st argument
unique_ptr(unique_ptr&& ptr) { ^ /Users/chaojie.mo/Documents/test/src/callback_utils.h:35:3: note: candidate constructor not viable: no known conversion from 'mcj::unique_ptr' to 'const unique_ptr &' for 1st argument
unique_ptr(const unique_ptr& other) = delete;

Can someone tell me how to improve mcj::unique_ptr to support that a derived class can cast to a base class?

CodePudding user response:

foo<B> is not a subclass of foo<B> in c . Google 'contravariance and covariance in c smart pointers',

You will have to extract the pointer cast it and create a new unique_ptr to return

  • Related