c++编译器会为类自动生成两个默认的取地址运算符重载函数(取普通对象地址、取const对象地址),但它们不属于“六大默认成员函数”,而是编译器隐式生成的辅助函数,且几乎不会被开发者手动修改(除非有特殊需求)。
一、取地址运算符重载的默认函数
1. 函数原型(以class cgoods为例)
| 函数类型 | 原型 | 作用 |
|---|---|---|
| 普通取地址运算符 | cgoods* operator&() | 返回非const对象的地址(this指针) |
| const取地址运算符 | const cgoods* operator&() const | 返回const对象的地址(const this) |
2. 编译器默认实现
编译器生成的默认版本逻辑极其简单:直接返回对象的this指针,等价于:
// 普通版本
cgoods* cgoods::operator&() {
return this; // 返回当前对象的地址
}
// const版本
const cgoods* cgoods::operator&() const {
return this; // 返回当前对象的const地址
}
二、使用示例(验证默认行为)
在你之前的cgoods类代码中,无需手动定义这两个函数,直接使用取地址符&即可:
int main() {
cgoods goods1("苹果", 9.9f);
const cgoods goods2("香蕉", 5.9f);
// 调用普通取地址运算符:operator&()
cgoods* p1 = &goods1;
cout << "普通对象地址:" << p1 << endl;
// 调用const取地址运算符:operator&() const
const cgoods* p2 = &goods2;
cout << "const对象地址:" << p2 << endl;
return 0;
}
输出结果(地址为示例,实际不同):
带参构造函数调用:苹果
带参构造函数调用:香蕉
普通对象地址:0x7ffeefbff5e0
const对象地址:0x7ffeefbff600
析构函数调用:释放 香蕉 的内存
析构函数调用:释放 苹果 的内存
三、关键特性说明
1. 生成条件
- 编译器总是会生成这两个默认函数,除非你显式手动定义了对应的版本(普通/const);
- 即使你定义了其他默认函数(如拷贝构造、移动赋值),这两个取地址函数仍会被生成。
2. 何时需要手动重载?
几乎不需要!只有极特殊场景下才会修改,比如:
- 禁止外部获取对象地址(返回nullptr);
- 对地址做特殊处理(如返回对象内部某个成员的地址)。
示例:手动重载取地址运算符(禁止获取地址)
class cgoods {
// ... 其他成员不变 ...
// 手动重载普通取地址运算符
cgoods* operator&() {
return nullptr; // 不返回真实地址
}
// 手动重载const取地址运算符
const cgoods* operator&() const {
return nullptr;
}
};
int main() {
cgoods goods("苹果", 9.9f);
cout << &goods << endl; // 输出 0(nullptr)
return 0;
}
3. 和六大默认函数的区别
| 维度 | 六大默认成员函数(构造/析构/拷贝/移动) | 取地址运算符重载函数 |
|---|---|---|
| 核心作用 | 管理对象生命周期/资源 | 提供对象地址的访问方式 |
| 生成优先级 | 显式定义后编译器不再生成 | 除非手动定义,否则始终生成 |
| 开发修改频率 | 高频(如深拷贝、移动语义) | 几乎为0(特殊场景才修改) |
| 异常风险 | 高(如内存泄漏、重复释放) | 极低(仅返回指针) |
总结
- 存在性:c++有取地址符相关的默认函数(两个版本:普通/const),但不属于核心六大默认成员函数;
- 默认行为:编译器生成的版本直接返回this指针,满足绝大多数场景需求;
- 使用建议:无需手动重载,只有禁止获取对象地址、修改地址返回逻辑等特殊场景才需要自定义;
- 核心记忆:取地址运算符重载是“辅助性默认函数”,优先级远低于构造/析构/拷贝/移动,日常开发几乎不用关注。
到此这篇关于c++ 取地址符相关的默认函数的文章就介绍到这了,更多相关c++ 取地址符内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论