如果不想使用编译器默认生成的函数,请明确拒绝它!

简介: 如果不想使用编译器默认生成的函数,请明确拒绝它!

1.问题引入


试想如下情形,某个房地产商所拥有的房子都是不同的。同时,你在为这个公司设计程序,而你不想将一座房子的信息拷贝给另一座房子,这就需要禁止使用拷贝构造函数和拷贝赋值运算符(copy assignment operator)。如下例所示:


1#include <iostream>
 2
 3class House
 4{
 5    // ...
 6};
 7
 8int main()
 9{
10    House h1;
11    House h2;
12    House h3(h1);  // 禁止执行默认的拷贝构造函数
13    h1 = h2;  // 禁止执行默认的拷贝赋值运算符
14
15    return 0;
16}


如果是其他功能,不想使用的话不声明即可。但是对于以上这两个功能,像昨天的文章C++类中默认生成的函数所说的。即使你不声明不定义,编译器还是会为该类自动生成的。


2.解决方法


解决方法:首先,因为编译器为类自动生成的函数都是共有(public)的,所以我们就可以把这些函数声明为私有(private),这样类生成的对象就无权限调用它们。其次,只声明不定义。因为如果有定义,本类和友元函数(friend functions)还是可以调用它们。如下例所示:


1#include <iostream>
 2
 3class House
 4{
 5public:
 6    // ...
 7private:
 8    House (const House&);  // 只声明,不定义拷贝构造函数。同时要设为private!由于根本就不会用到它们,所以可以不必写形参了
 9    House& operator=(const House&); // 只声明,不定义拷贝赋值运算符。同时要设为private!由于根本就不会用到它们,所以可以不必写形参了
10};


因此,当你在代码中试图拷贝对象,编译器就会报错。然而,如果你不小心在该类的成员函数或者友元函数中调用了private权限自动生成的函数,由于找不到自动生成函数的定义,链接器则会出错。但是,将所有报错提前到编译器不是更好吗?这样就可以越早的检测出错误了。


3.更好的解决方法


昨天的文章C++类中默认生成的函数中也提到了,当一个父类将拷贝构造函数和拷贝赋值运算符声明为私有时,编译器会拒绝为它的子类生成拷贝构造函数和拷贝赋值运算符因此我们可以专门使用一个父类,在父类当中声明拷贝操作为私有(private),并让我们的类继承自它。这样,当成员函数或友元函数试图拷贝House对象时,所有关于拷贝的操作都会提前在编译阶段报错。如下例所示:


1#include <iostream>
 2
 3class Uncopyable{
 4protected:
 5    Uncopyable(){}
 6    ~Uncopyable(){}
 7private:
 8    Uncopyable(const Uncopyable&);
 9    Uncopyable& operator=(const Uncopyable&);
10};
11
12class House: public Uncopyable{
13// ...
14};


4.总结


(1).当不想让编译器为类自动生成某些函数时,把这些不想要的函数声明在此类的私有成员中并不予以定义。或者,更好的方法使用像上例中定义一个Uncopyable父类,并让我们的House类公有继承自它。

相关文章
|
计算机视觉 Python
OpenCV形态学运算中梯度运算、顶帽、黑帽运算讲解与实战应用(附Python源码)
OpenCV形态学运算中梯度运算、顶帽、黑帽运算讲解与实战应用(附Python源码)
485 0
|
DataWorks 前端开发 IDE
重新定义研发模式,DataWorks 前端架构演进与 Serverless 实践之路
我们用多个大规模的应用实践告诉你,Serverless时代的前端在做什么。
重新定义研发模式,DataWorks 前端架构演进与 Serverless 实践之路
|
编解码 安全 算法
全双工通信 | 带你读《5G系统关键技术详解》之三
本书深入介绍了 5G 无线网络的协议、网络架构和技术,包括无线接入网络、移动边 缘计算、全双工、大规模 MIMO、毫米波、NOMA、物联网、M2M 通信、D2D 通信、 移动数据分流、干扰抑制技术、无线资源管理、可见光通信和智能数据定价等关键主题。
全双工通信  | 带你读《5G系统关键技术详解》之三
|
设计模式 消息中间件 安全
面试官:说说读写锁的实现原理?
面试官:说说读写锁的实现原理?
200 1
|
9月前
|
存储 数据采集 数据挖掘
CSV vs 数据库:数据存储的最佳选择是什么
本文介绍了爬虫数据存储中CSV和数据库的优缺点,分析了两者在不同场景下的适用性。CSV简单易用、资源消耗低,适合小量数据;数据库则在处理大量数据和复杂查询时表现出色,支持并发操作。通过Python代码示例,展示了如何使用多线程和爬虫代理IP技术将百度搜索数据存储到MySQL数据库中,适用于大型项目和复杂数据分析需求。
624 2
|
存储 NoSQL 关系型数据库
索引!索引!!索引!!!到底什么是索引?
**索引是数据库中的数据结构,类似书籍目录,加速数据查找和访问。优点包括提升查询性能、数据检索速度、支持唯一性约束及优化排序和连接操作。缺点在于增加写操作开销、占用存储空间、高维护成本和过多索引可能降低性能。常见的索引类型有单值、复合、唯一、聚集和非聚集索引等,实现方式涉及B树、B+树和哈希表。B树和B+树适合磁盘存储,B+树尤其适用于范围查询,哈希索引则适用于快速等值查询。**
1356 0
|
11月前
|
Java 大数据 API
别死脑筋,赶紧学起来!Java之Steam() API 常用方法使用,让开发简单起来!
分享Java Stream API的常用方法,让开发更简单。涵盖filter、map、sorted等操作,提高代码效率与可读性。关注公众号,了解更多技术内容。
411 5
|
存储 运维 5G
基于阿里云数据库 SelectDB 内核 Apache Doris 的实时/离线一体化架构,赋能中国联通 5G 全连接工厂解决方案
数据是 5G 全连接工厂的核心要素,为支持全方位的数据收集、存储、分析等工作的高效进行,联通 5G 全连接工厂从典型的 Lambda 架构演进为 All in [Apache Doris](https://c.d4t.cn/vwDf8R) 的实时/离线一体化架构,并凭借 Doris 联邦查询能力打造统一查询网关,数据处理及查询链路大幅简化,为联通 5G 全连接工厂带来数据时效性、查询响应、存储成本、开发效率全方位的提升。
1203 4
基于阿里云数据库 SelectDB 内核 Apache Doris 的实时/离线一体化架构,赋能中国联通 5G 全连接工厂解决方案
|
定位技术 数据处理
ptp 时钟同步
ptp 时钟同步
431 0
|
算法 数据挖掘
Faiss为啥这么快?原来是量化器在做怪!2
Faiss为啥这么快?原来是量化器在做怪!
634 1