Most concise way to disable copying class in C++11

后端 未结 4 1005
日久生厌
日久生厌 2021-02-05 08:28

I have a problem dealing with deprecated since C++11 default generation of copy constructor and copy assignment operator when there is a user-defined destructor.

For mos

相关标签:
4条回答
  • 2021-02-05 08:33

    You can do it by this(which is used by Caffe: a fast open framework for deep learning):

    // Disable the copy and assignment operator for a class.
    #define DISABLE_COPY_AND_ASSIGN(classname) \
    private:\
      classname(const classname&);\
      classname& operator=(const classname&)
    

    Usage example:

    class CNoCopyable{
    
        public:
            CNoCopyable(int i):m_d(i){}
    
        private:
            int m_d;
            // add this line(pass class name)
            DISABLE_COPY_AND_ASSIGN(CNoCopyable);
    
    };
    
    0 讨论(0)
  • 2021-02-05 08:34

    Deleting the copy-constructor and copy-assignment operator is the simplest and clearest way to disable copying:

    class X
    {
        X(X const &) = delete;
        void operator=(X const &x) = delete;
    };
    

    I don't follow what you are talking about with virtual destructors in the question body . It sounds like you're asking for a way to make your code take up fewer characters of source code, but also be more cryptic to anybody looking at it.

    If the list of deleted functions bothers you, you could hide them behind a macro, I guess.

     #define NON_COPYABLE_NOR_MOVABLE(T) \ 
          T(T const &) = delete; \
          void operator=(T const &t) = delete; \
          T(T &&) = delete;
    
    0 讨论(0)
  • 2021-02-05 08:39

    With C++11, a clean way is to follow the pattern used in boost (see here)

    You basically create a base class where copy constructor and copy assignment are deleted, and inherit it:

    class non_copyable
    {
    protected:
        non_copyable() = default;
        ~non_copyable() = default;
    
        non_copyable(non_copyable const &) = delete;
        void operator=(non_copyable const &x) = delete;
    };
    
    class MyClass: public non_copyable
    {
    ...
    }
    
    0 讨论(0)
  • 2021-02-05 08:51
    1. Only copy constructor and copy assignment operator will be generated when destructor is explicitly defaulted. And even then their generation is deprecated. So, in order to have virtual destructor and all default methods, one should write the following:

      struct Base
      {
          Base()=default;
          virtual ~Base() = default;
          Base(const Base&)=default;
          Base& operator=(const Base&)=default;
          Base(Base&&)=default;
          Base& operator=(Base&&)=default;
      };
      

      I would definitely use a macro for more than one such Base class.

    2. In case when destructor is defined by user, 2 special methods are still generated. There are the following ways to disable deprecated generating copy constructor and copy assignment operator:

      • delete move constructor OR move assignment operator (not quite self-explanatory but very short):

        Base(Base&&)=delete; // shorter than deleting assignment operator
        
      • delete both copy constructor and copy assignment operator:

        Base(const Base&)=delete;
        Base& operator=(const Base&)=delete;
        

      Note that you have to explicitly declare default constructor if you need it, e.g. Base()=default;.

      Macro or inheriting special class can be used as well for this purpose but I personally prefer deleting move constructor to implementing my own macro or base class. When using Qt or boost, I would prefer Q_DISABLE_COPY(Base) and inheriting boost::noncopyable respectively, because they are already implemented, widely known and recognizable.

    http://accu.org/index.php/journals/1896 - detailed explanation and rationale for these issues.

    0 讨论(0)
提交回复
热议问题