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;
}