c++ postfix / prefix operator overload as non-memb

2019-07-16 16:06发布

I am writing my own array class as an exercise. Since, I read non-member functions are actually better in some ways than member functions. (Scott Meyers)

I am trying to write as many operator overloads as non-member functions as possible. The operator overloads + , - all work out fine as non-member functions.

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

However, the prefix/postfix operators as non-member functions give issues (they work fine if I use scope resolution and make them member functions)

I understand that not every operator overload can be member functions. But , I am having trouble as to why these two cannot be non-member functions. The error I get is:

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

Which basically can be solved if I make them member functions and allow a *this array obj to be passed along in the following format.

(*this).operator++();

But the whole thing is, I do not want to make them member functions in first place! So, is it that the pre/post fix operators cannot/should not be implemented as non-member function?

The reasoning I came up with is that, since postfix/prefix is unary operator they only have one argument (usually a *this). So, if I want the compiler to provide the *this pointer implicitly and call the overloads, they must be implemented as a member-function.

Is My reasoning correct? If not how do I implement this as a non-member function? Thanks for providing me with some insight.

1条回答
地球回转人心会变
2楼-- · 2019-07-16 16:18

Perhaps I misunderstood, but if you're struggling with proper declaration of both operators, you can still do this with free operators like members. You do, however, need to pass the object as the first parameter by-reference. You're correct that as member functions they get their object for free via this. As a free function, you need to push it yourself.

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

Output

++obj called.
obj++ called.
查看更多
登录 后发表回答