title: Should I delete the move constructor and the move assignment of a smart pointer?
body: <p>I'm implementing a simple smart pointer, which basically keeps track of the number of references to a pointer that it handles.</p>
  
  <p>I know I <em>could</em> implement move semantics, but I don't think it makes sense as copying a smart pointer is very cheap. Especially considering that it introduces opportunities to produce nasty bugs.</p>
  
  <p>Here's my C++11 code (I omitted some inessential code). General comments are welcome as well.</p>
  
  <pre><code>#ifndef SMART_PTR_H_
  #define SMART_PTR_H_
  
  #include &lt;cstdint&gt;
  
  template&lt;typename T&gt;
  class SmartPtr {
  private:
      struct Ptr {
          T* p_;
          uint64_t count_;
          Ptr(T* p) : p_{p}, count_{1} {}
          ~Ptr() { delete p_; }
      };
  public:
      SmartPtr(T* p) : ptr_{new Ptr{p}} {}
      ~SmartPtr();
  
      SmartPtr(const SmartPtr&lt;T&gt;&amp; rhs);
      SmartPtr(SmartPtr&lt;T&gt;&amp;&amp; rhs) =delete;
  
      SmartPtr&lt;T&gt;&amp; operator=(const SmartPtr&lt;T&gt;&amp; rhs);
      SmartPtr&lt;T&gt;&amp; operator=(SmartPtr&lt;T&gt;&amp;&amp; rhs) =delete;
  
      T&amp; operator*() { return *ptr_-&gt;p_; }
      T* operator-&gt;() { return ptr_-&gt;p_; }
  
      uint64_t Count() const { return ptr_-&gt;count_; }
  
      const T* Raw() const { return ptr_-&gt;p_; }
  private:
      Ptr* ptr_;
  };
  
  template&lt;typename T&gt;
  SmartPtr&lt;T&gt;::~SmartPtr() {
      if (!--ptr_-&gt;count_) {
          delete ptr_;
      }
      ptr_ = nullptr;
  }
  
  template&lt;typename T&gt;
  SmartPtr&lt;T&gt;::SmartPtr(const SmartPtr&lt;T&gt;&amp; rhs) : ptr_{rhs.ptr_} {
      ++ptr_-&gt;count_;
  }
  
  template&lt;typename T&gt;
  SmartPtr&lt;T&gt;&amp; SmartPtr&lt;T&gt;::operator=(const SmartPtr&lt;T&gt;&amp; rhs) {
      if (this != &amp;rhs) {
          if (!--ptr_-&gt;count_) {
              delete ptr_;
          }
          ptr_ = rhs.ptr_;
          ++ptr_-&gt;count_;
      }
      return *this;
  }
  
  #endif // SMART_PTR_H_
  </code></pre>