news 2026/2/17 7:04:26

MyUniquePtr解引用运算符operator*和箭头运算符operator->

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyUniquePtr解引用运算符operator*和箭头运算符operator->

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

      • 完整测试案例代码
      • 代码编译运行说明
      • 关键代码解释
      • 总结

你希望我为MyUniquePtr中重载的解引用运算符operator*和箭头运算符operator->编写一个完整的测试案例,直观展示这两个运算符的使用方式和效果,这是理解智能指针核心行为的关键!

完整测试案例代码

我会先给出可直接编译运行的完整代码,包含MyUniquePtr的完整实现(带*/->重载),以及针对性的测试逻辑:

#include<iostream>#include<string>// 完整的MyUniquePtr实现(包含*和->重载)template<typenameT>classMyUniquePtr{public:// 普通构造:接管裸指针explicitMyUniquePtr(T*ptr=nullptr)noexcept:m_ptr(ptr){}// 禁用拷贝(unique_ptr核心特性)MyUniquePtr(constMyUniquePtr&)=delete;MyUniquePtr&operator=(constMyUniquePtr&)=delete;// 移动构造(必须noexcept,适配vector)MyUniquePtr(MyUniquePtr&&other)noexcept{m_ptr=other.m_ptr;other.m_ptr=nullptr;// 原对象置空,避免重复析构}// 移动赋值MyUniquePtr&operator=(MyUniquePtr&&other)noexcept{if(this!=&other){// 防止自赋值deletem_ptr;// 释放当前资源m_ptr=other.m_ptr;other.m_ptr=nullptr;}return*this;}// 析构:释放资源~MyUniquePtr()noexcept{deletem_ptr;m_ptr=nullptr;}// 重载解引用运算符:*ptr 访问对象本身T&operator*()constnoexcept{return*m_ptr;// 返回对象的引用,支持读写(const版本则返回const引用)}// 重载箭头运算符:ptr->func() 访问对象的成员T*operator->()constnoexcept{returnm_ptr;// 返回裸指针,编译器会自动拼接->调用成员}// 辅助函数:获取裸指针(验证用)T*get()constnoexcept{returnm_ptr;}private:T*m_ptr;// 管理的裸指针};// 测试用的业务类:包含成员变量和成员函数,方便测试*和->classPerson{public:// 构造函数:初始化成员Person(conststd::string&name,intage):m_name(name),m_age(age){std::cout<<"[Person构造] "<<m_name<<" ("<<m_age<<"岁)\n";}// 成员函数:展示信息voidshowInfo()const{std::cout<<"[Person信息] 姓名:"<<m_name<<",年龄:"<<m_age<<"\n";}// 成员函数:修改年龄voidsetAge(intnew_age){m_age=new_age;std::cout<<"[Person修改] "<<m_name<<"的年龄改为:"<<m_age<<"岁\n";}// 析构函数:验证资源释放~Person(){std::cout<<"[Person析构] "<<m_name<<"\n";}// 公开成员变量(方便测试*运算符直接访问)std::string m_name;intm_age;};// 主函数:测试*和->运算符intmain(){std::cout<<"===== 测试1:创建MyUniquePtr指向Person实例 =====\n";// 创建智能指针,接管Person对象MyUniquePtr<Person>ptr(newPerson("张三",25));std::cout<<"\n===== 测试2:使用operator*(解引用) =====\n";// 1. *ptr 访问对象本身,调用成员函数(*ptr).showInfo();// 2. *ptr 直接修改成员变量(因为返回的是引用)(*ptr).m_age=26;std::cout<<"[直接修改] 年龄改为26岁后:";(*ptr).showInfo();std::cout<<"\n===== 测试3:使用operator->(箭头) =====\n";// 1. ptr-> 调用成员函数(更简洁的写法,等价于(*ptr).func())ptr->showInfo();// 2. ptr-> 调用修改成员的函数ptr->setAge(27);// 3. ptr-> 直接访问成员变量std::cout<<"[箭头访问] 姓名:"<<ptr->m_name<<"\n";std::cout<<"\n===== 测试4:验证指针有效性 =====\n";std::cout<<"智能指针管理的裸指针地址:"<<ptr.get()<<"\n";std::cout<<"解引用后的对象地址:"<<&(*ptr)<<"\n";// &(*ptr) 等价于 ptr.get()std::cout<<"箭头运算符返回的指针地址:"<<ptr.operator->()<<"\n";std::cout<<"\n===== 程序结束(智能指针自动析构) =====\n";return0;}

代码编译运行说明

  1. 编译命令(GCC/Clang):
    g++ -std=c++11 unique_ptr_test.cpp -o unique_ptr_test ./unique_ptr_test
  2. 运行结果(清晰展示*和->的效果):
    ===== 测试1:创建MyUniquePtr指向Person实例 ===== [Person构造] 张三 (25岁) ===== 测试2:使用operator*(解引用) ===== [Person信息] 姓名:张三,年龄:25 [直接修改] 年龄改为26岁后:[Person信息] 姓名:张三,年龄:26 ===== 测试3:使用operator->(箭头) ===== [Person信息] 姓名:张三,年龄:26 [Person修改] 张三的年龄改为:27岁 [箭头访问] 姓名:张三 ===== 测试4:验证指针有效性 ===== 智能指针管理的裸指针地址:0x55f8b867e2a0 解引用后的对象地址:0x55f8b867e2a0 箭头运算符返回的指针地址:0x55f8b867e2a0 ===== 程序结束(智能指针自动析构) ===== [Person析构] 张三

关键代码解释

  1. operator*重载

    • 返回值是T&(对象的引用),因此*ptr可以直接操作原对象(读/写);
    • const修饰表示“调用该运算符的智能指针对象是const时,也能使用”;
    • noexcept标记是因为解引用指针本身不会抛异常(前提是指针非空,实际使用中建议先判空,比如if (ptr.get()) { ... })。
  2. operator->重载

    • 返回值是T*(裸指针),编译器会自动处理:ptr->showInfo()等价于(ptr.operator->())->showInfo()
    • 这是C++的语法糖,让智能指针的使用方式和裸指针完全一致,降低学习成本;
    • 同样加constnoexcept,保证异常安全和const正确性。
  3. 测试逻辑

    • (*ptr).showInfo():解引用后调用成员函数(语法上必须加括号,因为.的优先级高于*);
    • ptr->showInfo():箭头运算符更简洁,无需括号,是实际开发中最常用的写法;
    • (*ptr).m_age = 26/ptr->m_age:直接访问对象的成员变量,验证运算符支持读写。

总结

  1. operator*重载的核心作用:让智能指针支持*ptr语法,直接访问所指向的对象本身(返回引用,支持读写);
  2. operator->重载的核心作用:让智能指针支持ptr->成员语法,简洁访问对象的成员函数/变量(返回裸指针,编译器自动拼接->);
  3. 两个运算符的重载遵循“模拟裸指针行为”的设计原则,是智能指针能替代裸指针的关键语法特性。

补充:实际使用中建议给operator*增加空指针检查(比如抛出异常或断言),避免解引用空指针导致崩溃,比如:

T&operator*()const{if(!m_ptr){throwstd::runtime_error("解引用空的MyUniquePtr!");}return*m_ptr;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 13:30:55

机器学习 - 高斯判别分析(Gaussian Discriminant Analysis)

摘要&#xff1a;高斯判别分析&#xff08;GDA&#xff09;是一种基于高斯分布的生成式分类算法&#xff0c;通过建模各类别的多元高斯分布进行预测。该算法要求数据满足连续型、正态分布、协方差矩阵相同等假设条件。在Python中可通过scikit-learn的QuadraticDiscriminantAnal…

作者头像 李华
网站建设 2026/2/8 14:25:09

使用有向莱顿算法进行供应链/物料流转网络的集群划分

在智能制造体系中&#xff0c;供应链协同与物料流转效率直接决定生产交付能力。传统供应链管理常陷入“节点孤立分析”的困境&#xff0c;难以捕捉物料流转的方向性关联与集群特征。此前《使用莱顿算法在工厂中找出“一起出问题”的设备群》已展现莱顿算法在设备关联分析中的价…

作者头像 李华
网站建设 2026/2/16 4:01:33

Elasticsearch 搜索性能优化实战指南(生产级)

Elasticsearch 搜索性能优化实战指南(生产级) 一、索引设计进阶(决定上限) 1️⃣ 分片数的工程化计算方法(可落地) 经验公式: 目标分片数 ≈ 总数据量 / 30GB 示例: 预计 1 年数据量:3TB 3TB ≈ 3000GB 分片数 ≈ 3000 / 30 ≈ 100 个主分片 建议拆分: 按时间滚动…

作者头像 李华
网站建设 2026/2/15 19:27:31

Java计算机毕设之基于SpringBoot+Vue电影院订票选座系统基于Java web的电影院选票系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/2/11 3:19:05

精选的优秀法证分析工具和资源列表

精选的优秀免费&#xff08;大部分为开源&#xff09;取证分析工具和资源列表。 超棒的法医 收藏工具 分布框架现场取证IOC扫描仪获得成像雕刻记忆取证网络取证Windows 组件 NTFS/MFT 处理 OS X 取证移动取证Docker取证网络文物时间线分析磁盘映像处理解密管理图片分析元数据取…

作者头像 李华