当前位置: 首页 > 编程日记 > 正文

【Boost】noncopyable:不可拷贝

【CSDN】:boost::noncopyable解析
【Effective C++】:条款06_若不想使用编译器自动生成地函数,就该明确拒绝

1.example

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 Abrahamsnamespace 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;
#elsenoncopyable() {}~noncopyable() {}
#endif
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)noncopyable( const noncopyable& ) = delete;noncopyable& operator=( const noncopyable& ) = delete;
#elseprivate:  // emphasize the following members are privatenoncopyable( const noncopyable& );noncopyable& operator=( const noncopyable& );
#endif};
}typedef noncopyable_::noncopyable noncopyable;} // namespace boost#endif  // BOOST_CORE_NONCOPYABLE_HPP

2. noncopyable应用场景

1、单例模式各应用场景【略】
2、类内含指针,其指向动态创建的对象,如:

template<class T>
class HomeForSale
{
public:T* data;HomeForSale() { data = new T; }~HomeForSale() { delete data; }
}void copy()
{HomeForSale<Home> m1;HomeForSale<Home> m2;m1 = m2; 
}

执行拷贝后,m1.data指向m2.data所指对象,使m1.data无法释放以致内存泄露,再者还存在双重释放的问题
此情况可直接禁止拷贝,也可重载copy构造或copy assignment操作符解决【每次拷贝,内存删旧开新】

3. part two

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); //OKA a2(2); //OK//A a3 = a1; //编译不能通过//A a4(a1);  //编译不能通过A& a4 = a2;  //OKreturn 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;^

4. conclusion

解决问题:不声明copy构造或copy assignment操作符,编译器可能自动生成,使class支持copying,但自声明却依旧使得支持copying
解决方法:将两者 声明为private且不实现,阻止copying【private将链接期错误前移至编译期】
底层运行:客户企图拷贝,亦或member、friend函数调用拷贝,编译器都将阻挠
阻挠原因:因尝试拷贝时,编译器生成的copy构造或copy assignment操作符,被拒绝调用base class的对应兄弟【private】

noncopyable实现及运用 :
  1、不一定得public继承noncopyable,可private继承 【条款32 条款39】
  2、noncopyable析构不一定得是virtual 【条款7】
  3、noncopyable不含数据,符合空基类优化资格【条款39】
  4、作为基类,可能导致多继承【条款 40】,阻止空基类优化

相关文章:

BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览

一、引言时间到了2019年&#xff0c;数据库也发展到了一个新的拐点&#xff0c;有三个明显的趋势&#xff1a; 越来越多的数据库会做云原生(CloudNative)&#xff0c;会不断利用新的硬件及云本身的优势打造CloudNative数据库&#xff0c;国内以阿里云的Cloud HBase、POLARDB为代…

ubuntu clion 创建桌面快捷方式

ubuntu clion 创建桌面快捷方式 首先在终端下输入 cd /usr/share/applications/进入applications目录下&#xff0c;建立一个clion.desktop文件 sudo touch clion.desktop然后在vim命令下编辑该文件 sudo vim clion.desktop进入vim后&#xff0c;按i插入开始编辑该文件&…

Flex 布局:语法篇

2019独角兽企业重金招聘Python工程师标准>>> 布局的传统解决方案&#xff0c;基于盒状模型&#xff0c;依赖 display 属性 position 属性 float 属性。它对于那些特殊布局非常不方便&#xff0c;比如&#xff0c;垂直居中就不容易实现。 2009年&#xff0c;W3C 提…

特征运动点估计

cv::Mat getRansacMat(const std::vector<cv::DMatch>& matches, const std::vector<cv::KeyPoint>& keypoints1, const std::vector<cv::KeyPoint>& keypoints2, std::vector<cv::DMatch>& outMatches) {// 转换特征点格式std::vecto…

Vue+Element-ui+二级联动封装组件

通过父子组件传值 父组件&#xff1a; 1 <template>2 <linkage :citysList"citysList" :holder"holder" saveId"saveId"></linkage>3 </template>4 <script>5 import linkage from ./common/linkage6 export de…

MOG2 成员函数参数设定

pMOG2->setDetectShadows(true); // 背景模型影响帧数 默认为500 pMOG2->setHistory(1000); // 模型匹配阈值 pMOG2->setVarThreshold(50); // 阴影阈值 pMOG2->setShadowThreshold(0.7);前景中模型参数&#xff0c;设置为0表示背景&#xff0c;255为前景&#xff…

webpack 大法好 ---- 基础概念与配置(1)

再一次见面&#xff01; Light 还是太太太懒了&#xff0c;距离上一篇没啥营养的文章已经过去好多天。今天为大家介绍介绍 webpack 最基本的概念&#xff0c;以及简单的配置&#xff0c;让你能快速得搭建一个可用的 webpack 开发环境。 webpack的安装 webpack 运行于 node 环境…

Zookeeper迁移(扩容/缩容)

zookeeper选举原理在迁移前有必要了解zookeeper的选举原理&#xff0c;以便更科学的迁移。快速选举FastLeaderElectionzookeeper默认使用快速选举&#xff0c;在此重点了解快速选举&#xff1a;向集群中的其他zookeeper建立连接&#xff0c;并且只有myid比对方大的连接才会被接…

SVO Without ROS环境搭建

Installation: Plain CMake (No ROS) 首先&#xff0c;建立工作目录&#xff1a;workspace&#xff0c;然后把下面的需要的都在该目录下进行. mkdir workspace cd workspace Boost - c Librairies (thread and system are needed) sudo apt-get install libboost-all-dev Eige…

BackgroundSubtractorGMG 背景建模

#include <opencv2/bgsegm.hpp> #include <opencv2/video.hpp> #include <opencv2/opencv.hpp> #include <iostream> #include <sstream> using namespace cv; using namespace std; using namespace bgsegm; // GMG目标建模检测 void detectBac…

启动webpack-dev-server只能本机访问的解决办法

修改package.json的dev启动设置&#xff0c;增加--host 0.0.0.0启动后localhost更换为本机IP即可访问

TCP/IP:IP选项处理

引言 IP输入函数要对IP 进行选项处理&#xff0c;。RFC791和1122规定了IP选项和处理规则。一个IP首部可以跟40个字节的选项。 选项格式 选项的格式&#xff0c;分为两种类型&#xff0c;单字节和多字节。 ip_dooptions函数 这个函数用于判断分组转发。用常量位移访问IP选项字段…

【SVO2.0 安装编译】Ubuntu 20.04 + Noetic

ways one 链接: https://pan.baidu.com/s/1ZAkeD64wjFsDHfpCm1CB1w 提取码: kxx2 (downloads and use idirectly) ways two: [SVO2-OPEN: https://github.com/uzh-rpg/rpg_svo_pro_open](https://github.com/DEARsunshine/rpg_svo_pro_open)git挂梯子 如果各位终端无法挂梯…

人眼目标检测初始化

// 初始化摄像头读取视频流cv::VideoCapture cap(0);// 宽高设置为320*256cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);cap.set(CV_CAP_PROP_FRAME_HEIGHT, 256);// 读取级联分类器// 文件存放在opencv\sources\data\haarcascades bool flagGlasses false;if(flagGlasses){face_ca…

Qt之界面换肤

简述 常用的软件基本都有换肤功能&#xff0c;例如&#xff1a;QQ、360、迅雷等。换肤其实很简单&#xff0c;并没有想象中那么难&#xff0c;利用前面分享过的QSS系列文章&#xff0c;沃我们完全可以实现各种样式的定制&#xff01; 简述实现原理效果新建QSS文件编写QSS代码加…

mongDB的常用操作总结

目录 常用查询:查询一条数据查询子元素集合:image.idgte: 大于等于,lte小于等于...查询字段不存在的数据not查询数量:常用更新更新第一条数据的一个字段:更新一条数据的多个字段:常用删除删除:常用查询: 查询一条数据 精确匹配is Query(Criteria.where("id").is(id))…

【GTSAM】GTSAM学习

1 what GTSAM ? GTSAM 是一个在机器人领域和计算机视觉领域用于平滑&#xff08;smoothing&#xff09;和建图&#xff08;mapping&#xff09;的C库。它与g2o不同的是&#xff0c;g2o采用稀疏矩阵的方式求解一个非线性优化问题&#xff0c;而GTSAM是采用因子图&#xff08;f…

人脸、人眼检测与跟踪

#include <opencv2/opencv.hpp> #include <iostream> #include <vector> using namespace cv;CascadeClassifier face_cascade; CascadeClassifier eye_cascade;// 人眼检测 int detectEye(cv::Mat& im, cv::Mat& tpl, cv::Rect& rect) {std::v…

linux下jdk简单配置记录

记录哈&#xff0c;搭建环境的时候&#xff0c;copy使用方便。 vim /etc/profile export JAVA_HOME/usr/java/jdk1.7.0_79export PATH$JAVA_HOME/bin:$PATHexport CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarexport JRE_HOME$JAVA_HOME/jreexport LANGzh_CN.UT…

Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案

关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案 转载于:https://www.cnblogs.com/daemonFlY/p/10916812.html

so库方法原理

动态库 So库&#xff0c;又动态名库&#xff0c;是Linux下最常见的文件之一&#xff0c;是一种ELF文件。这种so库是程序运行时&#xff0c;才会将这些需要的代码拷贝到对应的内存中。但程序运行时&#xff0c;这些地址早已经确定&#xff0c;那程序引用so库中的这些代码地址如…

上传图片,多图上传,预览功能,js原生无依赖

最近很好奇前端的文件上传功能&#xff0c;因为公司要求做一个支持图片预览的图片上传插件&#xff0c;所以自己搜了很多相关的插件&#xff0c;虽然功能很多&#xff0c;但有些地方不能根据公司的想法去修改&#xff0c;而且需要依赖jQuery或Bootstrap库&#xff0c;所以我就想…

springboot 简单自定义starter - beetl

使用idea新建springboot项目beetl-spring-boot-starter 首先添加pom依赖 packaging要设置为jar不能设置为pom<packaging>jar</packaging> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web&…

cmake生成so包并调用(C++project,build,cmake)

1. 目录结构 2 . downloads 2.1 build module process CMakeLists.txt > cmake_minimum_required(VERSION 3.5)if(CMAKE_COMPILER_IS_GNUCC)message("COMPILER IS GNUCC")ADD_DEFINITIONS ( -stdc11 ) endif(CMAKE_COMPILER_IS_GNUCC)SET(CMAKE_CXX_FLAGS_DEBU…

人眼模板匹配自动跟踪

void trackEye(cv::Mat& im, cv::Mat& tpl, cv::Rect& rect) {// 人眼位置cv::Size pSize(rect.width * 2, rect.height * 2);// 矩形区域cv::Rect tRect(rect pSize - cv::Point(pSize.width/2, pSize.height/2));tRect & cv::Rect(0, 0, im.cols, im.rows);…

前端碎碎念 之 nextTick, setTimeout 以及 setImmediate 三者的执行顺序

『前端碎碎念』系列会记录我平时看书或者看文章遇到的问题&#xff0c;一般都是比较基础但是容易遗忘的知识点&#xff0c;你也可能会在面试中碰到。 我会查阅一些资料并可能加上自己的理解&#xff0c;来记录这些问题。更多文章请前往我的个人博客这个问题是有关执行顺序和Eve…

bat 将war文件转换成ear文件

1、无需拷贝war文件&#xff0c;自动获取war set path%path%;D:\jdk\jdk1.6.0_31\bin;C:\Program Files\7-Zip del **0001-controller.war del **0001-controllerEAR.ear copy ..\target\**0001-controller-0.0.1-SNAPSHOT.war **0001-controller.war rem 7z d -tzip **0001-co…

cmake语法【一】

一、Cmake 简介 cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。 二、常用命令 指定 cmake 的最小版本 cmake_minimum_required(VERSION 3.4.1)这行命令是可选的&#xff…

RHEL6.3安装vsftpd

1、下载vsftpd&#xff0c;可以从官网&#xff08;http://vsftpd.beasts.org&#xff09;下载&#xff0c;也可以百度搜索[rootlocalhost vsftpd]# wget http://down1.chinaunix.net/distfiles/vsftpd-3.0.2.tar.gz2、解压压缩包并进入解压出来的目录[rootlocalhost vsftpd]# t…

创建mysql数据库,在新数据库中创建表,再尝试删除表

创建之前&#xff0c;先登录数据库存 mysql -u 账号 -p密码 登录完成后&#xff0c;展示一下已存在的数据库 show databases; 创建数据库 create database test111; 然后展示一下数据库&#xff0c;如下 show databases; 使用数据库 use test; 在test数据库里面看一下已存在的…