C++ 的运算符重载功能使得类的操作更加灵活。常见的操作符如 + - 等十分容易理解,但有些运算符重载的含义却不是那么清晰。这篇博客来看两个运算符的重载,解引用运算符 * 和成员访问运算符 ->

重载解引用运算符

当一个类希望重载解引用操作符时,说明这个类希望自己可以表现的像一个指针一样,因为只有指针才有解引用的需求。这不就是 C++ 的智能指针类嘛!就拿智能指针类举例子,可能类中最重要的成员就是一个真正的指针,其指向一块动态内存,而智能指针类就希望自己表现得像这个指针一样,只不过其内部封装了更多的保证安全的行为。

首先,解引用操作符是个一元操作符。其次,重载解引用操作符要求返回的类型是一个引用,之所以是引用是因为通常在解引用完后还要修改对应变量的值,例如 *ptr = 3 。其他也没啥注意的了,下面上一下代码:

template<typename T>
class cls {
public:
    T& operator*() {
        return *ptr;
    }
private:
    T* ptr;
};

重载成员访问操作符

类似的,需要重载成员访问操作符 -> 的类也希望自己表现的像一个指针一样,且自己指向的是类类型。这同样是智能指针的需求。

比较反直觉的,成员访问操作符是个一元操作符,其操作数是左边的类指针。C++ 规定重载成员访问操作符必须返回一个指针或者一个类对象。而返回了指针或者类对象之后又如何解释呢?看下面的例子

cls obj;
obj->Print();

假设 cls 类重载了 -> ,则 obj->Print() 被解释为 (obj.operator->())->Print() ,即对该函数的返回值再次调用 -> 。可知此时有两种情况,假如函数真的返回了一个指针,那这就相当于对该指针施行成员访问操作。假如函数返回的是一个类对象,则继续调用这个类对象的 operator->() ,这样就会循环下去,直到某一级返回了指针。当然正常情况下直接返回指针就行了,没必要搞那么复杂。下面是个例子:

template<typename T>
class cls {
public:
    T* operator->() {
        return ptr;
    }
private:
    T* ptr;
}
Last modification:April 14th, 2020 at 05:01 pm