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