boost::noncopyable
为什么要boost::noncopyable
在c++中定义一个类的时候,如果不明确定义拷贝构造函数和拷贝赋值操作符,编辑器会为我们自动生成。
但是有时候我们不需要类的复制语义,希望禁止复制类的实例。这时一个很经典的C++惯用语法,只要私有化拷贝构造函数和拷贝赋值操作函数即可。
boost中的noncopyable为实现不可拷贝类提供了简单清晰的解决方案。
boost::noncopyable源码
// Boost noncopyable.hpp header file --------------------------------------//
// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
#ifndef BOOST_CORE_NONCOPYABLE_HPP
#define BOOST_CORE_NONCOPYABLE_HPP
#include <boost/config.hpp>
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:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
BOOST_CONSTEXPR noncopyable() = default;
~noncopyable() = default;
#else
noncopyable() {}
~noncopyable() {}
#endif
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
noncopyable( const noncopyable& ) = delete;
noncopyable& operator=( const noncopyable& ) = delete;
#else
private: // emphasize the following members are private
noncopyable( const noncopyable& );
noncopyable& operator=( const noncopyable& );
#endif
};
}
typedef noncopyable_::noncopyable noncopyable;
} // namespace boost
#endif // BOOST_CORE_NONCOPYABLE_HPP
class noncopyable的基本思想就是把构造函数和析构函数设置为protected权限,这样子类可以调用,但是外面的类不能调用,当子类需要定义构造函数的时候可以编译通过。将拷贝构造函数和赋值构造函数设置为private,这就意味着除非子类定义自己的拷贝构造函数和拷贝赋值操作函数,否则外面的调用者不能够通过拷贝构造和赋值等手段产生一个新的子类对象的。
验证
文件test.cpp
#include<iostream>
#include <boost/noncopyable.hpp>
class A : boost::noncopyable {
public:
A(int a) {
std::cout << a << std::endl;
}
};
int main(){
A a1(1); //OK
A a2(2); //OK
//A a3 = a1; //编译不能通过
//A a4(a1); //编译不能通过
A& a4 = a2; //OK
return 0;
}
编译出错:
In file included from /usr/local/include/boost/noncopyable.hpp:15:0,
from test.cpp:2:
/usr/local/include/boost/core/noncopyable.hpp: 在复制构造函数‘A::A(const A&)’:
/usr/local/include/boost/core/noncopyable.hpp:38:7: 错误:‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’是私有的
noncopyable( const noncopyable& );
^
test.cpp:4:7: 错误:在此上下文中
class A : boost::noncopyable {
^
test.cpp: 在函数‘int main()’中:
test.cpp:14:9: 附注:在这里第一次需要生成的方法‘A::A(const A&)’
A a3 = a1;
^