C++基础/限定符及一些关键字在限定函数的作用

在学习中发现对const在限定函数的作用有些模糊,以下为笔者的学习总结

1.5cv限定符及一些关键字在限定函数的作用

  1. c(const)v(volatile)

    • const:用于表示该函数不会改变类的成员变量,所以是可以修改全局变量的

    • volatile:用于告诉编译器该对象可能会被程序外部修改

      #include <iostream>
      #include <string>
      
      int year = 2023; // 全局变量
      
      class Peoson {
      private:
      	std::string name;
          int age;
      
      public;
          void getYear() const {
          	// age = 1; 错误
          	year = getYear(); // 全局变量,可以修改
          	std::cout << year << endl;
      }
      };
      
      int main() {
          Person m;
          m.getYear();
          
          return 0;
      }
      
    • 例:

      1. const 限定符:

      const 用于声明一个常量对象,表示该对象的值不能被修改。例如:

      const int x = 5; // x 是一个常量整数,值不能改变
      // x = 10; // 这行会导致编译错误
      
      1. volatile 限定符:

      volatile 用于告诉编译器该对象可能会被程序以外的因素(如硬件)改变,因此不要对其进行优化。例如:

      volatile int sensor_value; // 这个值可能会被硬件设备随时更改
      
      1. 同时使用 const 和 volatile:
      const volatile int real_time_clock; // 值不能被程序修改,但可能会被硬件更新
      
      1. mutable 说明符:

      mutable 允许在 const 对象中修改特定成员。例如:

      class Example {
          mutable int cache_value;
      public:
          void update_cache() const {
              cache_value = 42; // 即使在 const 方法中也可以修改
          }
      };
      

      这些限定符主要用于:

      • 防止意外修改(const)
      • 处理可能被外部因素更改的数据(volatile)
      • 在需要时允许局部修改(mutable)
  2. &(左值)和&&(右值):表明该函数只能被左值或右值调用

    #include <iostream>
    
    class MyString {
    public:
        void Print() & {
            std::cout << "左值" << std::endl;
        }
        
        void Print() && {
            std::cout << "右值" << std::endl;
        }
    };
    
    int main() {
        MyString test;
        test.Print();     // 左值
        MySting().Print();// 右值
        
        return 0;
    }
    
  3. 显式调用成员函数(C++23新特性):

    • 左值:代表有明确地址和持久对象(在内存中存在且可以被引用),例如变量 dcd
    • 右值:代表临时对象或字面量,通常是没有持久地址的。例如 std::move(d) 会将 d 转换为一个右值引用(Derived&&)。
    class MyClass {
    public:
        void normalFunction(int x) {
            // 隐式调用
            value = x;
        }
        
        // 2。
        void explicitFunciton(this MyClass& self, int x) {
            // 显式调用
            self.value = x;
        }
        
        // 3.
        template<typename Self>
        void anyExplicitFunction(this Self& self, int x) {
            self.value = x;
        }
        
    private:
        int value;
    };
    
    MyClass test;
    test.normalFunction(1);
    test.explicitFunciton(1);
    test.anyExplicitFunction(1); // 这里是左值调用,所以self是&test且为非const
    // 效果是一样的
    
  • 当我们调用test.explicitFunciton(1);的时候,编译器把其转换成了类似于这样的代码MyClass::explicitFunciton(test, 1);

  • 第二种优势

    清晰性: 显式地看到 this 参数可以使代码意图更清晰。

    灵活性: 可以更灵活地控制 this 的类型,比如是否为 const, 是左值还是右值引用等。

    模板推导: 在模板中,可以推导出 this 的确切类型,这在继承情况下特别有用。

  • 第三种优势

    它能自动处理 const 和非 const 对象。

    它能处理左值和右值。

  • 例子

    class Base {
    public:
        template<typename Self>
        void print(this Self&& self) {  //直接写&&,会根据调用的参数来决定是左值还是右值
            std::cout << "I am " << self.getName() << std::endl;
        }
    
        virtual std::string getName() const { return "Base"; }
    };
    
    class Derived : public Base {
    public:
        std::string getName() const override { return "Derived"; }
    };
    
    int main() {
        Base b;
        Derived d;
        const Derived cd;
    
        b.print();   // 输出: I am Base
        d.print();   // 输出: I am Derived
        cd.print();  // 输出: I am Derived,注意这里调用的是 const 版本
    
        // 使用右值
        std::move(d).print();  // 也能正确工作,Self 被推导为 Derived&&
        // std::move(<对象名>) // 把对象从左值转换为右值
    }
    
  • 如果传的对象是const对象,只能调用const类型的成员函数,那么该函数会转换为const类型,反之非const,即为非const类型函数

  • 虽然这些特性的业务作用普通的类和对象都支持,但是这有着更简介的写法,让代码易于维护

    • 更简洁的写法:通过简化函数模板的定义,使得代码更简洁。

      易于维护:清晰的语法和显式的 this 参数声明有助于提高代码的可读性和维护性。

      减少重载:能够在一个模板中处理不同的 this 类型,减少了重载函数的需求,简化了代码结构。

参考链接
[ https://zh.cppreference.com/w/cpp/language/member_functions#const.E3.80.81volatile_.E5.8F.8A.E5.BC.95.E7.94.A8.E9.99.90.E5.AE.9A.E7.9A.84.E6.88.90.E5.91.98.E5.87.BD.E6.95.B0​ ]:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值