当前位置: 首页 > news >正文

如何禁止C++类对象的禁止拷贝操作

如何禁止C++类对象的禁止拷贝操作

类对象禁止拷贝

只需要在将构造函数声明为如下形式即可

class A { public: A() = default; private: A(const A&) = delete; };

如果使用下面的声明则会报错

int main() { A a; A b = a; // compile-time error }

运行g++编译会报错

main.cpp: In function ‘int main()’: main.cpp:10:15: error: use of deleted function ‘A::A(const A&)’ 10 | A b = a; | ^ main.cpp:5:9: note: declared here 5 | A(const A&) = delete; | ^

禁止使用操作符=

struct Counter { int* p; Counter(int v) { p = new int(v); } ~Counter() { delete p; } }; int main() { Counter a(1); Counter b(2); a = b; }

使用gdb调试,设置断点在a=b

(gdb) print a $1 = {p = 0x55555556aeb0} (gdb) print *a No symbol "operator*" in current context. (gdb) print b $2 = {p = 0x55555556aed0}

可以看出ab中的成员变量p的值是不同的

现在step next,再看看a和b的值

18 } (gdb) print a $7 = {p = 0x55555556aed0} (gdb) print b $8 = {p = 0x55555556aed0}

我们可以看到,二者都一样了,即两个变量的成员变量p都指向了同一个地址,地址内的值是2

(gdb) print *a->p $9 = 2 (gdb) print *b->p $10 = 2

然后退出主函数之前调用析构函数

(gdb)s Counter::~Counter(this=0x7fffffffdd00,__in_chrg=<optimized out>)at main.cpp:99delete p;(gdb)n10}(gdb)print this->p$13=(int *)0x55555556aed0(gdb)print *this->p$14=1431655786

可以看到地址内的值已被其他的值替换

问题是删除了a的值,那b的值也删除了,原来a的p值并没有被delete

(gdb) print /x *0x55555556aeb0 $17 = 0x1

相当于这里有个指针变量被悬空了,由于C++没有垃圾回收,那么这个内存就一直占据内存,如果数量庞大则会导致内存溢出。

如果要避免这种情况的发生,则可使得运算符设置为不允许拷贝

struct Counter { int* p; Counter(int v) { p = new int(v); } ~Counter() { delete p; } Counter& operator=(const Counter&) = delete; }; int main() { Counter a(1); Counter b(2); a = b; }

使用g++进行编译

jx@jx-virtual-machine:~/src/cpp$ g++ main.cpp -o main main.cpp: Infunction‘int main()’: main.cpp:19:7: error: use of deletedfunction‘Counter&Counter::operator=(const Counter&)19|a=b;|^ main.cpp:12:12: note: declared here12|Counter&operator=(const Counter&)=delete;|^~~~~~~~
http://www.jsqmd.com/news/144641/

相关文章:

  • 基于MATLAB的HSV颜色特征杂草图像识别系统设计与实现
  • 2026 必藏!十大设计师、美工、运营素材网站!正版狂喜! - 品牌2026
  • 2025-2026年口碑好的烟尘在线监测仪制造商推荐:哪家做得好+哪家性价比高+知名品牌 - 品牌推荐大师1
  • 2025年市场知名的横梁货架厂商推荐榜,阁楼货架/仓储货架/货架/重型货架/穿梭式货架,横梁货架直销厂家口碑推荐 - 品牌推荐师
  • Dapper 异常情况记录
  • 2026 十大高清免费版权图片素材下载网站推荐,合规商用冲! - 品牌2026
  • 基于大数据的国产跑鞋推荐与可视化分析系统(毕设源码+文档)
  • 2025年三效废水蒸发处理定做厂家权威推荐榜单:石墨多效蒸发器/三效蒸发系统/钢衬石墨蒸发源头厂家精选 - 品牌推荐官
  • 2025年12月江苏徐州装修、装修设计、装修施工、设计工作室、别墅设计哪家专业可靠 - 2025年品牌推荐榜
  • 智能音乐推荐小程序的设计与实现开题报告
  • 铜箔加工制造商推荐:一站式服务+快速打样(附案例) - 品牌排行榜
  • AI浪潮下的前端范式转移:从代码实现者到思维架构师
  • 上海铜箔制造企业综合实力榜(2025选型指南)——军工级定制与快速交付视角 - 品牌排行榜
  • 利尔达荣获维科杯·OFweek2025物联网行业杰出标杆企业奖
  • 学长亲荐10个AI论文软件,自考毕业论文轻松搞定!
  • indent and unindent in vscode and its descendant when tab/shift-tab not work
  • 最新上海装修公司口碑排名:零投诉+15000平生产基地 - 品牌排行榜
  • 互联网大厂面试攻略:Java小白如何应对微服务与云原生技术
  • 2026 十大图库推荐:找可下载图片素材的靠谱平台清单 - 品牌2026
  • Android Studio - 解决 Using ‘jvmTarget: String‘ is an error. Please migrate to the compilerOptions DSL
  • 盘点2025年口碑最佳的无线信号测量仪表品牌,无线电综合测试测试仪/光通信测量仪表/频谱仪/电子对抗设备无线信号测量仪表品牌推荐排行榜 - 品牌推荐师
  • PC实心板品牌影响力:29年市场验证 + 用户口碑(品牌价值) - 品牌排行榜
  • Unity WebGL jslib 通信时,传入字符串,变成数值 问题
  • 华东铜箔公司实力推荐:新能源应用+技术创新(2025采购参考) - 品牌排行榜
  • 新手必备!8大公众号运营免费神器全面测评(2025最新版)
  • 2025年12月餐巾纸/卫生纸/抽纸/卷纸/擦手纸公司实力排行推荐 - 2025年品牌推荐榜
  • 2025专科生必看!9个AI论文工具测评,写毕业论文不再难
  • 超低温机组哪个厂家好?2025超低温机组制造商推荐,为选型提供权威参考 - 品牌推荐大师1
  • 七载同行共铸卓越,利尔达展芯荣膺纳芯微“风雨同舟奖”!
  • 不同操作系统下MySQL安装详细指南与步骤解析