Override operator= for non-class (ie primitive) types like int, char *, etc.

May 27, 2008 at 10:03pm
I have a problem which I can't seem to find others who have the same problem. I have a custom class, call it foomatic. I want to define how foomatic is reference in assignments with =. For example, consider the following code:

foomatic object1;
string object1Name;
int object1Size;

objectName = object1;
object1Size = object1;

Here, I have control of the object on the right of the =...the rvalue. I don't have control over the objects on the left side of the =. I know that I could extend string class in this example, but I don't want to create a new class for every custom object. This means I would have to go through ALL my source code and update the extended string class, for example, just so I can make the above code valid. Furthermore, I am not even aware of a way to override operator= for primitive types, such as int, or char *, etc.

Thanks,
Anthony

May 27, 2008 at 10:32pm
You can do as you want.

1
2
3
4
5
6
7
8
9
10
class foomatic {

public:
 operator string() {
  return name;
 }
 operator int() {
  return size;
 }
}
May 27, 2008 at 10:35pm
You need to override the = operator in the global namespace (outside of your class).

1
2
3
4
5
int& operator = ( int& i, const foomatic& foo )
  {
  i = foo.x + foo.y;
  return i;
  }

Obviously, the function overload needs to be a friend to foomatic.

Now you can say things like

int n = foomatic( 29, 13 );

Just keep in mind that at least one of the operands must be a user-defined type (like a class).

If you want more information, a simple Google of "c++ operator overloading" produces some nice results.

Hope this helps.

[edit] Hey Zaita, you on the east cost of USA also?
Also, I can't believe I forgot that one. Nice!
Last edited on May 27, 2008 at 10:36pm
May 27, 2008 at 10:39pm
New Zealand :)
11.50am Wednesday here.
May 28, 2008 at 5:44am
Douas:
You need to override the = operator in the global namespace (outside of your class).

No. That isn't possible. You can do that with other binary operators, but the assignment operator must be a non-static member function. Zaita's solution should work, but he better declare the operators const:
1
2
3
4
5
6
7
8
9
10
class foomatic {

public:
 operator string() const {
  return name;
 }
 operator int() const {
  return size;
 }
}
May 28, 2008 at 12:34pm
Argh. That's one of those silly gotchas that always get me...
May 28, 2008 at 6:20pm
Wow, such great I will try these out today. I will post back up to confirm which solution worked.

Thanks!
May 28, 2008 at 6:55pm
Ropez: That's more in his implementation. Maybe he wants to alter the returned name at some point. Because it's being returned by value rather than reference the const keyword would only be a preference thing.
May 28, 2008 at 7:41pm
So, Zaita's suggestion worked and so did ropez's additon of "const". What exactly is set as constant with ropez's solution? Does it set the returned object/variable constant?
Last edited on May 28, 2008 at 7:45pm
May 28, 2008 at 7:49pm
Nothing. Because the operator returns a value, not a reference.

"Const methods are a way for us to say that a method does not modify the member variables of a class. It's a hint both to the programmer and the compiler that a given method doesn't change the internal state of a class."

"is often missed is that by extension a const method cannot call a non-const method (and the compiler will complain if you try). Since we assume that a non-const method does modify the member variables of our class, we can't call that from a method where we've promised not to do just that."
Last edited on May 28, 2008 at 7:54pm
May 28, 2008 at 8:23pm
The const keyword in this case has nothing to do with the return type. It's necessary to qualify the function as const to be able to call it with a const foomatic object as receiver ("this").

Without the const keyword, this code won't compile:
1
2
3
void foo(const foomatic& f) {
  int i = f;
}


Since the assignment doesn't change the rvalue, it should be possible to do this even with a const reference. Therefore, you should add the const keyword.

BTW: The error message would be something like "calling operator int() discards qualifiers".
May 28, 2008 at 8:27pm
Hmmm indeed correct. Does this offer any optimization benefits when using the const keyword?
May 28, 2008 at 8:29pm
What exactly is set as constant with ropez's solution?


The implicit first parameter.

All member function has a "hidden" parameter called this, e.g.
1
2
3
4
5
6
7
8
9
// Member function:
void A::f();
// Basically the same as:
void f(A* this);

// Const member function:
void A::f() const;
// Basically the same as passing "this" as a const pointer:
void f(const A* this);
May 28, 2008 at 8:32pm
Does this offer any optimization benefits when using the const keyword?

Not that I know of, but an interesting question.
Topic archived. No new replies allowed.