在C++中,箭头运算符的重载是一种例外情况还是遵循与其他运算符的情况相同的逻辑?

问题描述 投票:0回答:1

我有一个关于箭头运算符的重载过程的问题。重载使其看起来像是一元运算符,而用法使其看起来像二元运算符。返回值也不直观。仅返回原始指针。

#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 被替换。接下来的任何事情都与直觉一致。中间步骤让我烦恼。箭头运算符的重载过程是特例吗?

这只是一个理论问题。

c++ logic operator-overloading return-value theory
1个回答
0
投票

是的,箭头运算符是一种特殊情况。这是因为内置的

->
运算符本身就是一个例外情况。对于所有其他二元运算符,参数是指定对象的表达式,因此
x ⊕ y
的含义与
x.operator⊕(y)
相同(⊕ 是任何非例外的二元运算符)。

然而,在

x->y
中,
y
不是对象,而是指定类成员的标识符。人们不能将这样的东西作为参数传递给用户定义的函数,
x.operator->(y)
毫无意义。因此,
x->y
被改为表示
x.operator->()->y
,以便
x
表现得像指针一样。因此,重载的
operator->
需要是一元的,而不是二进制的。

© www.soinside.com 2019 - 2024. All rights reserved.