2

我正在编写自己的数组类作为练习。因为,我读到非成员函数实际上在某些方面比成员函数更好。(斯科特迈耶斯

我正在尝试尽可能多地编写非成员函数的运算符重载。运算符重载 + , - 作为非成员函数都可以正常工作。

my_array operator+(const my_array & left, const my_array & right);
my_array operator-(const my_array & operand);
my_array & operator++();  // prefix
my_array   operator++(int); //postfix, compiler puts a 0

但是,作为非成员函数的前缀/后缀运算符会产生问题(如果我使用范围解析并将它们设为成员函数,它们就可以正常工作)

我知道并非每个运算符重载都可以是成员函数。但是,我对为什么这两个不能是非成员函数感到困惑。我得到的错误是:

: 'my_array& operator++()' must have an argument of class or enumerated type

如果我将它们设为成员函数并允许 *this 数组 obj 以下列格式传递,这基本上可以解决。

(*this).operator++();

但整件事是,我不想让它们首先成为成员函数!那么,是不是 pre/post fix 运算符不能/不应该被实现为非成员函数?

我想出的理由是,由于后缀/前缀是一元运算符,它们只有一个参数(通常是 *this)。因此,如果我希望编译器隐式提供 *this 指针并调用重载,则必须将它们实现为成员函数。

我的推理正确吗?如果不是,我如何将其实现为非成员函数?感谢您为我提供一些见解。

4

1 回答 1

3

也许我误解了,但是如果您在正确声明两个运算符时遇到困难,您仍然可以使用像成员这样的免费运算符来做到这一点。但是,您确实需要将对象作为第一个参数按引用传递。你是正确的,作为成员函数,他们通过this免费获得他们的对象。作为免费功能,需要自己推送。

#include <iostream>

struct my_array
{
    // your members here.
};

my_array& operator ++(my_array& obj)
{
    // access to members is through obj.member
    std::cout << "++obj called." << std::endl;
    return obj;
}

my_array operator ++(my_array& obj, int)
{
    my_array prev = obj;

    // modify obj, but return the previous state.        
    std::cout << "obj++ called." << std::endl;

    return prev;
}

int main(int argc, char *argv[])
{
    my_array obj;
    ++obj;
    obj++;
    return 0;
}

输出

++obj called.
obj++ called.
于 2013-09-13T15:15:53.390 回答