@zephyr
Articles8
Tags10
Categories0
c++ noncopyable-object

c++ noncopyable-object

c++禁用拷贝构造

众所周知,move的开销低于copy,只需要交换指针即可转移堆上内存的所有权。并且很多时候我们不需要同时保留两份实例,我们甚至希望某个资源是独占的,这时候就可以禁用它的拷贝构造函数:

1
2
3
4
5
{
T(const T&) = delete;
T& operator=(const T&) = delete;
}

这样它就只能move,不能copy了。不过每次都要这样写一遍,实在太麻烦。更好的做法是定义一个不能copy的基类,让其他类去继承它。只要不能通过copy构造基类,自然也就没法继续去构造子类了。

boost库中刚好有noncopyable,可以拿来借鉴一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace noncopyable_
{
#ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED
#define BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED

struct base_token {};

#endif

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:
noncopyable( const noncopyable& );
noncopyable& operator=( const noncopyable& );
#endif
};
}

typedef noncopyable_::noncopyable noncopyable;

虽然加了一堆宏定义(为了兼容老版本cpp),但是核心内容就只有两点: 把默认构造函数的访问权限设定为protected,这样只有继承它的子类才可以访问(构造);把拷贝构造函数删除或者屏蔽(设定为private)。

以后只要以private权限继承noncopyable,就可以愉快的玩耍了(我看还是rust来的实在)

Author:@zephyr
Link:https://zephyr.moe/2021/12/27/cpp-notes-1/
License:CC BY-NC-SA 3.0 CN