Assignment operator overloading with class on right

I'm trying to overload an operator so I can assign my class to an int like so:
1
2
MyClass a;
int b = a;


I know that I need to use the friend keyword to access the private member of a, but I'm getting some errors that I can't explain.

This is example code:
... replaced with my edit below

EDIT: Okay forget the friend part. This seems just weird:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass
{
public:
    int member;
    MyClass() : member(0) {}
};

int& operator = (int &L, MyClass &R)
{
    L = R.member;
    return L;
}

int main()
{
    MyClass a;
    int b = a;
}

1>Snippets.cpp(9): error C2801: 'operator =' must be a non-static member
1>Snippets.cpp(17): error C2440: 'initializing' : cannot convert from 'MyClass' to 'int'
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Is there a rule against overloading the assignment operator with a basic type on the left or is there something else that I'm missing?
Last edited on
One more thing...

Can someone explain why this works? It seems to work upon both compiling and testing, however I don't understand why I have access to the right-hand-side's private members.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyClass
{
    int member;
public:
    MyClass() : member(0) {}
    MyClass& operator = (MyClass &B)
    {
        member = B.member;
        return *this;
    }
};

int main()
{
    MyClass a, b;
    b = a;
}
Last edited on
1>Snippets.cpp(9): error C2801: 'operator =' must be a non-static member
1>Snippets.cpp(17): error C2440: 'initializing' : cannot convert from 'MyClass' to 'int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


There are a few C++ operators that can only be overloaded as class members:
They are = -> () [] (assignment, pointer to member, function call and array subscript)

As for the other thing - objects of class T has access to any member of of another object of class T - otherwise the whole class thing wouldn't work.
Last edited on
closed account (zb0S216C)
The assignment operator must be a non-static member of the class. It cannot be overridden globally. This applies to all assignment forms (+=, <<=, -=, and so on).

Stewbond wrote:
"I don't understand why I have access to the right-hand-side's private members."

All native members have access to the private and protected parts of the class. This is because functions, operators, and data members are all part of the same class. As to why access is given, I'm not too sure.

Also, a valid overload of the assignment operator for your class must take a reference to a constant class object.

Wazzak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyClass
{
public:
    int member;
    MyClass() : member(0) {}


	operator int() { return member ; }
};

int main()
{
    MyClass a;
    int b = a;
}
Thanks for the explanation guys! Classes are implicitly friends with themselves. This makes sense and the explicit int cast idea is perfect for my assignment issue.
Last edited on
Hello guys I have a little question.

Actually when I am overloading an assignment operator for a class, say, class Money:

class Money
{
public:
...
Money& operator =(const Money& amount); <-?????????? Option 1
void operator =(const Monet& amount); <-?????????? Option 2
...
private:
int dollar;
int cents;
}

Which of the two options is the correct overloading declaration?

And by the way, I don't quite get how the keyword THIS is used... Can't I just overload the operator = like below:

void Money::operator =(const& money amount)
{
dollar = amount.dollar;
cents = amount.cents;
}

And done? What is the THIS for???
closed account (zb0S216C)
The call to Money::operator = () will be ambiguous because the return-type alone isn't enough to distinguish between overloads. To disambiguate the call, at least 2 of the following must differ from the rest of the overloads:

- Return-type
- Function constness
- Parameters

Wazzak
Last edited on
i dont understand what you are talking about... perhaps put it this way, how has option 1 completed the things that you have mentioned?
maybe i put it the other way too...

void Money::operator =(const& money amount)
{
dollar = amount.dollar;
cents = amount.cents;
}

Money& operator=(const& Money amount)
{
dollar = amount.dollar;
cents = amount.cents;
return *this;
}

Money operator=(const& Money amount)
{
dollar = amount.dollar;
cents = amount.cents;
return *this;
}

Exactly, in what ways do the three overloading of the assignment operators differ from each other??? All the three look the same to me but I suppose I must be wrong?
closed account (zb0S216C)
Neither of the 3 are different; maybe to you, but not the compiler. To differentiate a function from the other overloads, At least two of the following must differ:

- Return-type
- Function constness
- Parameters

Here's 3 contrary overloads:

1
2
3
4
5
6
7
8
9
struct Structure
{
    // Overload 1:
    Structure &operator = (Structure const &S);
    // Overload 2:
    Structure const &operator = (Structure const &S) const;
    // Overload 3:
    void operator = (int const &Int);
};

See the differences between each overload?

Wazzak
Hmm I guess I get what you mean now...

To conclude: All three of the definitions are the same, it's more or less the difference of programmers' style?

Bosco
The correct implementation of the operator= is to return a reference to the type of the class. So in your original example, you should return a Money&. The point of this is to allow some code like this:
1
2
Money a, b, c;
a = b = c;

If the assignment operator did not return a reference, this wouldn't work.

As for your other question, the this pointer exists to allow you to explicitly reference members of your own class, though as you see it is implied and can be omitted in many (if not all) cases. Another (and IMO more important) reason for it to be there is so you can check for self-assignment by comparing the address of the right-hand side of the operator to this.
Note that the copy and swap idiom eliminates the need to check for self assignment.
Topic archived. No new replies allowed.