我有一个关于箭头运算符的重载过程的问题。重载使其看起来像是一元运算符,而用法使其看起来像二元运算符。返回值也不直观。仅返回原始指针。
#include <iostream>
template <typename T>
class Auto_ptr1
{
T* m_ptr {};
public:
// Pass in a pointer to "own" via the constructor
Auto_ptr1(T* ptr=nullptr)
:m_ptr(ptr)
{
}
// The destructor will make sure it gets deallocated
~Auto_ptr1()
{
delete m_ptr;
}
// Overload dereference and operator-> so we can use Auto_ptr1 like m_ptr.
T& operator*() const { return *m_ptr; }
T* operator->() const { return m_ptr; }
};
// A sample class to prove the above works
class Resource
{
public:
Resource() { std::cout << "Resource acquired\n"; }
~Resource() { std::cout << "Resource destroyed\n"; }
void sayHi() { std::cout << "Hi!\n"; }
};
void someFunction()
{
Auto_ptr1<Resource> ptr(new Resource()); // ptr now owns the Resource
int x;
std::cout << "Enter an integer: ";
std::cin >> x;
if (x == 0)
return; // the function returns early
// do stuff with ptr here
ptr->sayHi();
}
int main()
{
someFunction();
return 0;
}
在 ptr->sayHi() 示例中,人们可能期望整个表达式 ptr-> 被替换为原始指针,但显然,只有 ptr 被替换。接下来的任何事情都与直觉一致。中间步骤让我烦恼。箭头运算符的重载过程是特例吗?
这只是一个理论问题。
是的,箭头运算符是一种特殊情况。这是因为内置的
->
运算符本身就是一个例外情况。对于所有其他二元运算符,参数是指定对象的表达式,因此 x ⊕ y
的含义与 x.operator⊕(y)
相同(⊕ 是任何非例外的二元运算符)。
然而,在
x->y
中,y
不是对象,而是指定类成员的标识符。人们不能将这样的东西作为参数传递给用户定义的函数,x.operator->(y)
毫无意义。因此,x->y
被改为表示 x.operator->()->y
,以便 x
表现得像指针一样。因此,重载的 operator->
需要是一元的,而不是二进制的。