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

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

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;
 }
}
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
New Zealand :)
11.50am Wednesday here.
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;
 }
}
Argh. That's one of those silly gotchas that always get me...
Wow, such great I will try these out today. I will post back up to confirm which solution worked.

Thanks!
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.
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
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
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".
Hmmm indeed correct. Does this offer any optimization benefits when using the const keyword?
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);
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.