首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
安全
›
主机安全
›
C++11&QT复习 (五)
返回列表
发新帖
C++11&QT复习 (五)
[复制链接]
发表于 2025-10-8 20:23:30
|
显示全部楼层
|
阅读模式
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
Day6-2 成员访问运算符重载(2025.03.25)
1. 复习
在上一节中,我们学习了 C++ 中的
输入输出流运算符重载(<< 和 >>)
以及
下标运算符 [] 和函数调用运算符 ()
的重载。本节我们将重点学习
成员访问运算符(-> 和 *)的重载
。
2. 成员访问运算符重载
C++ 答应用户自界说类的成员访问方式,此中 ->(箭头运算符)和 *(解引用运算符)是最常见的运算符之一。它们通常用于模仿智能指针或多层指针访问。
2.1 箭头运算符 (->) 重载
(1) 语法
class A {
public:
B* operator->();
};
复制
代码
作用
:
答应 A 类的对象
像指针一样访问 B 类的成员
。
范例用途是在
封装指针
的类(如智能指针)中重载 operator->,使得用户无需手动解引用即可访问目标对象的成员。
注意事项:
返回值必须是一个指针大概引用
,否则无法继续访问成员变量或函数。
假如返回的是对象的引用
,则可以实现多层 -> 重载。
operator->
不能改变调用对象自身
,因此通常
不应该声明为 const 成员函数
。
2.2 解引用运算符 (*) 重载
(1) 语法
class A {
public:
B& operator*();
};
复制
代码
作用
:
答应 A 类的对象
像指针一样举行解引用
。
常见于智能指针的实现,使 *ptr 直接返回对象的引用,方便访问其成员。
注意事项:
返回值一样寻常是引用
(如 B&),如许不会产生额外的拷贝。
实用于
封装指针
的类,如智能指针或署理类。
3.
代码
分析
#include <iostream>
using namespace std;
class Data
{
public:
Data(int data = 0)
:_data(data)
{
cout << "Data(int data = 0)" << endl;
}
~Data()
{
cout << "~Data()" << endl;
}
int getData() const
{
return _data;
}
private:
int _data;
};
class SecondLayer
{
public:
SecondLayer(Data* pData)
:_pData(pData)
{
cout << "SecondLayer(Data* pData)" << endl;
}
//重载 -> 运算符
Data* operator->()
{
return _pData;
}
//解引用重载运算符
Data& operator*()
{
return *_pData;
}
~SecondLayer()
{
cout << "~SecondLayer()" << endl;
if (_pData)
{
delete _pData;
_pData = nullptr;
}
}
private:
Data* _pData;
};
class ThirdLayer
{
public:
ThirdLayer(SecondLayer* pSecond)
:_pSecond(pSecond)
{
cout << "ThirdLayer(SecondLayer* pSecond)" << endl;
}
//重载 -> 运算符
SecondLayer& operator->()
{
return *_pSecond;
}
~ThirdLayer()
{
cout << "~ThirdLayer()" << endl;
if (_pSecond)
{
delete _pSecond;
_pSecond = nullptr;
}
}
private:
SecondLayer* _pSecond;
};
void test()
{
/*Data* data = new Data(1);
SecondLayer* second = new SecondLayer(data);
ThirdLayer* third = new ThirdLayer(second);*/
SecondLayer second(new Data(10));//栈对象
//A类的对象调用B类的成员函数
/*cout << "&second : " << &second << endl;
cout << "second.operator->() :" << second.operator->() << endl;*/
// 重载operator->
cout << "second.operator->()->getData() :" << second.operator->()->getData() << endl;
cout << "second->getData() :" << second->getData() << endl;
// 重载operator*
cout << "(*second).getData()" << (*second).getData() << endl;
ThirdLayer third(new SecondLayer(new Data(30)));//栈对象
cout << "third->getData() : " << third->getData() << endl;
//还原
cout << "third.operator->().operator->()->getData()" << third.operator->().operator->()->getData();
}
int main(int argc, char** argv)
{
test();
test();
return 0;
}
复制代码
3.1 代码布局
上面的代码实现了一个
三层封装
的指针署理类,分别是:
Data:数据类,包罗一个 _data 成员变量。
SecondLayer:封装 Data* 指针,并重载 operator-> 和 operator*。
ThirdLayer:封装 SecondLayer* 指针,并重载 operator->。
3.2 代码分析
(1) Data 类
class Data
{
public:
Data(int data = 0) : _data(data)
{
cout << "Data(int data = 0)" << endl;
}
~Data()
{
cout << "~Data()" << endl;
}
int getData() const
{
return _data;
}
private:
int _data;
};
复制代码
Data 类封装了一个 int 范例的数据 _data,提供了 getData() 方法用于获取数据值。
构造函数、析构函数用于跟踪对象的创建和烧毁。
(2) SecondLayer 类
class SecondLayer
{
public:
SecondLayer(Data* pData) : _pData(pData)
{
cout << "SecondLayer(Data* pData)" << endl;
}
// 重载 -> 运算符
Data* operator->()
{
return _pData;
}
// 解引用运算符 *
Data& operator*()
{
return *_pData;
}
~SecondLayer()
{
cout << "~SecondLayer()" << endl;
if (_pData)
{
delete _pData;
_pData = nullptr;
}
}
private:
Data* _pData;
};
复制代码
封装 Data* 指针,并提供访问 Data 成员的方式
。
operator->() 返回 _pData 指针,使得 SecondLayer 对象
可以像指针一样使用 -> 访问 Data 的方法
。
operator*() 返回 _pData 所指向的 Data 对象的引用,使 *second 直接返回 Data 对象。
示例:
SecondLayer second(new Data(10));
cout << second->getData() << endl; // 等价于 second.operator->()->getData()
cout << (*second).getData() << endl; // 等价于 second.operator*().getData()
复制代码
(3) ThirdLayer 类
class ThirdLayer
{
public:
ThirdLayer(SecondLayer* pSecond) : _pSecond(pSecond)
{
cout << "ThirdLayer(SecondLayer* pSecond)" << endl;
}
// 重载 -> 运算符
SecondLayer& operator->()
{
return *_pSecond;
}
~ThirdLayer()
{
cout << "~ThirdLayer()" << endl;
if (_pSecond)
{
delete _pSecond;
_pSecond = nullptr;
}
}
private:
SecondLayer* _pSecond;
};
复制代码
ThirdLayer 封装了 SecondLayer* 指针,并提供 operator->() 使其
可以像 SecondLayer 一样使用 -> 访问 Data 的方法
。
实现两层 -> 重载
,使得 ThirdLayer 可以连续访问 Data 成员。
示例:
ThirdLayer third(new SecondLayer(new Data(30)));
cout << third->getData() << endl; // 等价于 third.operator->().operator->()->getData()
复制代码
3.3 运行 test() 方法
void test()
{
SecondLayer second(new Data(10));
cout << "second->getData() :" << second->getData() << endl;
cout << "(*second).getData()" << (*second).getData() << endl;
ThirdLayer third(new SecondLayer(new Data(30)));
cout << "third->getData() : " << third->getData() << endl;
cout << "third.operator->().operator->()->getData() : " << third.operator->().operator->()->getData();
}
复制代码
输出:
Data(int data = 0)
SecondLayer(Data* pData)
second->getData() : 10
(*second).getData() : 10
Data(int data = 0)
SecondLayer(Data* pData)
ThirdLayer(SecondLayer* pSecond)
third->getData() : 30
third.operator->().operator->()->getData() : 30
~ThirdLayer()
~SecondLayer()
~Data()
~SecondLayer()
~Data()
复制代码
SecondLayer 答应访问 Data 对象。
ThirdLayer 答应访问 SecondLayer,终极可访问 Data。
多层指针访问的署理模式收效
,而且析构时正确开释了内存。
4. 总结
运算符作用实用场景返回值范例operator->()答应对象像指针一样访问成员智能指针、署理类指针或引用operator*()答应对象像指针一样解引用智能指针、署理类引用
关键点:
operator->() 必要返回指针或引用
,可以连续调用 ->。
operator*() 必要返回对象的引用
,制止拷贝,进步
性能
。
实用于封装指针的类,如智能指针和署理类
。
本节学习了
成员访问运算符 -> 和 * 的重载
,把握它们的用法可以更好地明白
智能指针
和
署理模式
。
回复
使用道具
举报
返回列表
浏览过的版块
DevOps与敏捷开发
物联网
Oracle
向量数据库
Java
数据仓库与分析
Mysql
分布式数据库
SQL-Server
.Net
半亩花草
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表