Boost(4):boost::noncopyable类详解

本文解析了boost::noncopyable类的作用及其实现原理,通过示例展示了如何禁止类被复制,并探讨了不同编译环境下该类的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 说明

在上一篇的示例中在说明封装抽象类时有用到boost::noncopyable类,在实际使用的很多情况下,加没加这个类似乎对我的操作没有影响,那么这个类到底有什么作用呢,在这篇笔记中详细分析一下。

1.1 noncopyable作用

其官方说明是:Private copy constructor and copy assignment ensure classes derived from class noncopyable cannot be copied.大意是将私有化类的拷贝构造函数和拷贝赋值操作符,这样子类可以调用,但是外部调用者不能通过复制/赋值等语句来产生一个新的对象。

boost::noncopyable主要的用法是作为父类供其他类继承其特性。

2. 示例

这里定义了两个类Test1和Test2,其中Test2继承boost::noncopyable的特性

#include <iostream>

#include <boost/noncopyable.hpp>

class Test1 {
    public:
    Test1(int i) {std::cout << "This is Test1 that is copyable" << std::endl;}
};

class Test2 : boost::noncopyable {
    public:
    Test2(int i) {std::cout << "This is Test2 that is noncopyable" << std::endl;}
};

int main()
{
    Test1 t1(1);
    Test2 t2(2);

    Test1 t3 = t1;    // It's OK
    Test1 t4(t1);     // It's OK

    Test2 t5 = t2;    // Cannot be referenced
    Test2 t6(t2);     // Cannot be referenced
    Test2 &t7 = t2;   // It's OK

    return 0;
}

直接编译时会报错,如下:

g++ test.cpp

test.cpp: In function ‘int main()’:
test.cpp:23:16: error: use of deleted function ‘Test2::Test2(const Test2&)’
   23 |     Test2 t5 = t2;    // Cannot be referenced
      |                ^~
test.cpp:10:7: note: ‘Test2::Test2(const Test2&)’ is implicitly deleted because the default definition would be ill-formed:
   10 | class Test2 : boost::noncopyable {
      |       ^~~~~
test.cpp:10:7: error: use of deleted function ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’
In file included from /usr/local/include/boost/noncopyable.hpp:15,
                 from test.cpp:3:
/usr/local/include/boost/core/noncopyable.hpp:49:7: note: declared here
   49 |       noncopyable( const noncopyable& ) = delete;
      |       ^~~~~~~~~~~
test.cpp:24:16: error: use of deleted function ‘Test2::Test2(const Test2&)’
   24 |     Test2 t6(t2);     // Cannot be referenced

从编译信息可以看出,Test2不支持使用复制的方式来实例化类。

3. boost::noncopyable类详解

boost::noncopyable定义在 <boost/core/noncopyable.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
{
#ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED
#define BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED

// noncopyable derives from base_token to enable Type Traits to detect
// whether a type derives from noncopyable without needing the definition
// of noncopyable itself.
//
// The definition of base_token is macro-guarded so that Type Trais can
// define it locally without including this header, to avoid a dependency
// on Core.

  struct base_token {};

#endif // #ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED

  class noncopyable: base_token
  {
  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

注意其中的关键语句:

#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

BOOST_NO_CXX11_DELETED_FUNCTIONS类重载了复制和"=“运算符,将它们变为"delete”。上面的语句中如果没有定义BOOST_NO_CXX11_DELETED_FUNCTIONS类,那么直接实现了重载运算符的功能,如果有定义,则将这两个运算符变成私有成员。即无论如何,noncopyable类下复制和"="运算符都被重载为"delete"了。

参考资料

https://www.boost.org/doc/libs/1_78_0/libs/core/doc/html/core/noncopyable.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翔底

您的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值