• C++ 类和对象篇(八) const成员函数和取地址运算符重载


    目录

    一、const成员函数

    1. const成员函数是什么?

    2. 为什么有const成员函数?

    3. 什么时候需要使用const修饰成员函数? 

    二、取地址运算符重载

    1. 为什么需要重载取地址运算符?

    2. 默认取地址运算符重载函数

    3. 默认const取地址运算符重载函数

    4. 什么时候要显示重载取地址运算符? 

    【总结】


    一、const成员函数

    1. const成员函数是什么?

            const修饰的成员函数称为const成员函数,这个const是用来修饰隐藏的this指针的,表明在该成员函数中不能对类的任何成员进行修改。

    1. class B{
    2. public:
    3. int func()const
    4. {
    5. }
    6. };
    7. const修饰的“成员函数”称之为 const成员函数,const修饰类成员函数,
    8. 实际修饰该成员函数隐含的 this指针,表明在该成员函数中不能对类的任何成员进行修改。

    2. 为什么有const成员函数?

    0.const成员函数的出现解决了两个问题:

    • 如何保证无法通过成员函数修改成员变量?
    • const对象无法调用非const成员函数。

    1. const成员函数保证了无法通过该成员函数修改成员变量


    2. const成员函数能被const对象调用,不会产生权限放大问题。


    3. 为什么const对象无法调用非const成员函数? 

            每个成员函数第一个参数都是隐藏的this指针,对象在调用成员函数时会将对象的地址传给这个this指针,但将const对象传给this指针就会造成权限放大问题。

            this 指针本身是 类名* const 类型的,比如Date类的this指针类型是 Date* const,这里的const在*后面,不同于const Date对象取地址后的类型:const Date* 【在*之前修饰,代表该指针指向对象的内容不能被修改(地址里的内容不能改);在*之后修饰,代表该指针指向的对象不能被修改(指向的地址不能改)】,而且const 对象只有读权限,而this指针*前没const修饰有读写权限,所以对象在调用成员函数将对象的地址传给这个this指针时,会造成权限放大问题。

    3. 什么时候需要使用const修饰成员函数? 

            如果一个函数中不需要修改成员变量,建议加const进行修饰,因为const成员函数const对象可以调用,非const对象也可以调用。但要注意:const成员函数内无法调用其它的非const成员函数。


    请思考下面的几个问题:

    1. const对象可以调用非const成员函数吗?
      答案:不可以,传递this指针时权限会放大。
    2. 非const对象可以调用const成员函数吗?
      答案:可以,传递this指针时权限缩小。
    3. const成员函数内可以调用其它的非const成员函数吗?
      答案:不可以,传递this指针时权限会放大。
    4. 非const成员函数内可以调用其它的const成员函数吗?
      答案:可以,传递this指针时权限缩小。

            


    二、取地址运算符重载

    1. 为什么需要重载取地址运算符?

            在上篇文章「C++ 类和对象篇 7」运算符重载中,分析了重载运算符的原因:为了让自定义类型能使用运算符。重载取地址运算符的目的也是如此:让自定义类型也能使用取地址运算符(&)来获取其内存地址。

    2. 默认取地址运算符重载函数

            类中有6个默认成员函数,其中就有默认取地址运算符重载函数,所以即使类中没有定义取地址运算符重载函数,对象依然能使用取地址运算符(&):

    3. 默认const取地址运算符重载函数

            const取地址运算符重载函数也是默认成员函数,所以即使类中没有定义取地址运算符重载函数,const对象依然能使用取地址运算符(&):

    4. 什么时候要显示重载取地址运算符? 

            一般不需要写,编译器生成的默认的取地址和const取地址运算符重载函数完全够用。特殊情况下,比如不想让别人获取对象的地址,就可以自己实现,返回nullptr:

    1. 如果不想让别人获取对象的地址,就可以重载取地址运算符,返回nullptr
    2. class A
    3. {
    4. public:
    5. A* operator&()
    6. {
    7. return nullptr;
    8. }
    9. const A* operator&()const
    10. {
    11. return nullptr;
    12. }
    13. };
    14. int main()
    15. {
    16. A a;
    17. const A b;
    18. cout << &a << endl;
    19. cout << &b << endl;
    20. return 0;
    21. }

    5.  取地址运算符重载可以写在类外,目前我们学到的只有赋值运算符只能在类中重载。


    【总结】

     


    ------------------------END-------------------------

    才疏学浅,谬误难免,欢迎各位批评指正。

  • 相关阅读:
    Eclipse配置Maven详细教程
    Google Earth Engine ——影像无法正差加载可能是可视化参数设置得问题(visParams)
    Maven仓库jar包无法找到,编译失败,报红
    简单粗暴提升yolov5小目标检测能力
    现代PCB生产工艺——加成法、减成法与半加成法
    设计模式详解之单例模式
    【RocketMq 系列】RocketMq 入门教程
    9.19~9.20elf论文(浮点数的二进制表示&确定擦除尾随0的数量)
    JavaEE——传输层_UDP
    Ubuntu/Debian/CentOS搭建Socks5代理一键脚本
  • 原文地址:https://blog.csdn.net/look_outs/article/details/133710305