c++pointerssmart-pointersmove-semanticsstdmove

My own Smart pointer Implementation is creating issue with move operation


In the below code, the output is turning out to be blank instead of constructor and destructor printouts. Without move operation, the code is working well. I am somehow messing up the move operation, please go through and give your inputs to guide further.

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;

template <class T>
class smart{
    public:
    smart():pt{nullptr}{
        
    }
    smart(T *ptr):pt{ptr}{
        
    } 
    
    T *pt;
    smart(const smart& ob)=delete;
    smart operator=(const smart& ob)=delete;

    smart (smart&& dyingob){
        this->pt=dyingob.pt;
        dyingob.pt=nullptr;
    }
    void operator=(smart&& dyingob){
        pt=dyingob.pt;
        dyingob.pt=nullptr;
    }
    T* operator ->(){return this->pt;};
    ~smart(){
        if(pt!=nullptr)
        delete pt;
    }
};
class A{
    public:
    A(int n){
        data=n;
        cout<<"\nconstructed";
    }
    ~A(){
        cout<<"\ndestructed";
    }
    int data;
};
int main()
{
    smart<A> ob(new A(5));
   smart<A> ob1;
   ob1=(std::move(ob));
    cout<<ob->data;
    return 1;
}

Solution

  • When noticing unexpected behavior, the first thing to check for is compiler warnings. But - without very specific flags perhaps - you are not likely to get those here.

    However, a second thing to check for is what a static analysis tool tells you about your program. Let's try clang-tidy (version 14) for example:

    1 warning generated.
    /tmp/a.cpp:51:11: warning: Method called on moved-from object 'ob' [clang-analyzer-cplusplus.Move]
        cout<<ob->data;
              ^~~~
    /tmp/a.cpp:50:4: note: Object 'ob' is moved
       ob1=(std::move(ob));
       ^~~~~~~~~~~~~~~~~~~
    /tmp/a.cpp:51:11: note: Method called on moved-from object 'ob'
        cout<<ob->data;
              ^~~~
    

    So, you're acting on a moved-from object (like commenters also told you... e.g. @songyuangyo). ob->data is a nullptr after the move, is it not?