Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must (), [], ->, and = be overloaded only as member functions? [closed]

I tried to analyse why some of the operators ((), [], ->, =) should be overloaded as member functions only. I failed and I tried to search on internet but of no use. Can any one please help me to understand this restriction?

like image 210
kadina Avatar asked Sep 13 '25 23:09

kadina


2 Answers

I think this is most likely why that portion of the standard was written that way.

but if it is not forbidden, the friend version would never be called, in my testing code ,when

 Complex operator+(const Complex &other);

is defined as private, the compiler would give error message

‘Complex Complex::operator+(const Complex&)’ is private
 Complex Complex::operator+(const Complex &other)

instead of using the friend version

refer to Why cannot a non-member function be used for overloading the assignment operator?

Because the default operator= provided by the compiler (the memberwise copy one) would always take precedence. I.e. your friend operator= would never be called.

(If the assignment was performed inside a class method, because of the lookup rules, the member function (in this case generated by the compiler) would take precedence)

I try to using operator + for test. it prove the precedence

it outputs:

member function called
7+11i

testing code:

#include<iostream>
using namespace std;
class Complex
{
public:
    Complex(int real, int imag);
    Complex(void);
    ~Complex(void);

    Complex &Add(const Complex &other);

    void Display() const;

    Complex operator+(const Complex &other);

    friend Complex operator+(const Complex &c1, const Complex &c2);

private:
    int real_;
    int imag_;
};
Complex::Complex(int real, int imag): imag_(imag), real_(real)
{

}
Complex::Complex(void)
{
}

Complex::~Complex(void)
{
}

Complex &Complex::Add(const Complex &other)
{
    real_ += other.real_;
    imag_ += other.imag_;
    return *this;
}


void Complex::Display() const
{
    cout << real_ << "+" << imag_ << "i" << endl;
}


Complex Complex::operator+(const Complex &other)
{
    int r = real_ + other.real_;
    int i = imag_ + other.imag_;
    std::cout << "member function called"<< std::endl;
    return Complex(r, i);
}

Complex operator+(const Complex &c1, const Complex &c2)
{
    int r = c1.real_ + c2.real_;
    int i = c1.imag_ + c2.imag_;
    std::cout << "friend function called"<<std::endl;
    return Complex(r, i);
}

int main(void)
{
    Complex c1(3, 5);
    Complex c2(4, 6);


    Complex c3 = c1 + c2;

    c3.Display();

    return 0;
}
like image 59
michaeltang Avatar answered Sep 15 '25 12:09

michaeltang


Certain forms of operators require access to the "this" pointer of an instance of a class in order to operate directly on that instance as they only take a single argument to the same type.

class A{
public:

    int x;

    // only takes a reference to another 'A' type, so we need the 'this' pointer
    A& operator=(const A& other){
        this->x = other.x;
        return *this;
    }
};
like image 40
mbradber Avatar answered Sep 15 '25 14:09

mbradber