C++如何禁止掉对象的复制操作

最容易想到的是将拷贝构造函数与赋值函数声明为private。但是,private只是说外部不能直接调用,但是可以间接通过类的成员函数与友元函数对其访问。那么怎么办呢?

----》在类中,允许声明函数,但是,可以不用实现该函数,这是合法的。那么即使是在public中声明函数,但是不实现,那么调用这个函数也是会出错的。


那么好了我们可以特性一起使用,将拷贝构造函数与赋值函数,声明为private,并且不给出实现这样就实现了类复制的完全禁止。

用户代码中的复制尝试将在编译时标记为错误,而成员函数与友元函数中的复制尝试将在链接时出现错误。

上面介绍的这种技术在你熟悉的std::iostream类中已经得到了很好的应用,诸如ios_base、basic_ios和sentry,都采用这样的方式不允许复制操作。


Boost为我们提供了另一种解决方式,这种方式更加完美,因为它可以将链接错误提前到编译时,毕竟早一点发现错误比晚发现要好。

特意声明一个不可复制的类boost::noncopyable

#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED  
#define BOOST_NONCOPYABLE_HPP_INCLUDED  
  
namespace boost {  
  
//  Private copy constructor and copy assignment ensure classes derived from  
//  class noncopyable cannot be copied.  
  
//  Contributed by Dave Abrahams  
  
namespace noncopyable_  // protection from unintended ADL  
{  
  class noncopyable  
  {  
   protected:  
      noncopyable() {}  
      ~noncopyable() {}  
   private:  // emphasize the following members are private  
      noncopyable( const noncopyable& );  
      const noncopyable& operator=( const noncopyable& );  
  };  
}  
  
typedef noncopyable_::noncopyable noncopyable;  
  
} // namespace boost  
  
#endif  // BOOST_NONCOPYABLE_HPP_INCLUDED  


为了禁止拷贝对象,我们只需要让其私有继承自boost::noncopyable,

class student:private boost::noncopyable

{

......

}

当调用到派生类的拷贝构造函数或赋值函数进行复制时,不可避免的要调用基类对应的函数,因为这些操作是private,这样的操作会被编译器拒绝。

需要注意,多重继承有时会使空基类noncopyable优化失效,所以这不适合用于多重继承的情形。



另外,如果只是不想要使用默认的拷贝构造函数或赋值函数,可以使用C++11提供的delete,

C++11则使用delete关键字显式指示编译器不生成函数的默认版本。比如:

class MyClass
{
  public:
    MyClass()=default;
    MyClass(const MyClass& )=delete;
  ......
}

当然,一旦函数被delete过了,那么重载该函数也是非法的,该函数我们习惯上称为删除函数。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章