Operators OverriddingFiled Under: Weekly Tuesday Dose of goodness
Ah… don’t we love to harness the power of C++? Operators. What are they?
They’re the little < , > , <= , >= , == , != , ! , = and so on. There’s basically a few types of operators.
In C++, we can actually override these to make nice effects in our codes. That is, making our codes look cleaner while work harder in between the operators.
So you think…
We’ll just talk about the following operators:
1) >
2) <
3) >=
4) <=
5) ==
6) !=
First, what are these operators for? They’re, for some people, meant to make code look nicer and neater, therefore making it easier to maintain.
Classic Example: Maths Vector class - cVector4
This class is a simple 4 floating-pointer attribute class. Naturally, you’d want to perform operators to manipulate the vector, such as dot product.
So, in order to perform a standard dot product, it’ll look something like this:
cVector4 v1, v2, v3; //assume that v2 and v3 is set to some value
v1.x = v2.x * v3.x;
v1.y = v2.y * v3.y;
v1.z = v2.z * v3.z;
If you’ve used a canonical operator * , it’ll roughly performs the following:
cVector4& cVector4::operator * (const cVector4& copy)
{
cVector4 retValue;
retValue.x = this->x * copy.x;
retValue.y = this->y * copy.y;
retValue.z = this->z * copy.z;
return retValue;
}
Coupled with the canonical assignment operator, it allows the following code to run without errors:
cVector4 v1, v2, v3; //assume that v2 and v3 is set to some value
v1 = v2 * v3; // 1), 2)
1) The operator * does the job to perform a dot product between v2 and v3
2) The assignment operator = does the job of assignment the derived values into v1
Looks wonderful right? Looks elegant right?
Well, there’re always caveats in everything we do. Don’t assume that operators can override some of the operations. Also do not assume that operators can be done carelessly. This would lead to a series of possible bugs that will eventually cripple your application to a point where you’ll face hell to try troubleshooting it.
You’ll most likely get shot down by the magnitude of codes you have to troubleshoot.
For operators == , < , <= , > , >= , these operators return a specific boolean condition as they’re comparator operators. Unlike Java where you have to inherit a special and confusing interface known as Comparator (p.s. it simply means that if you’re poor in English, good luck in using Java), in C++, operators are used instead for elegance and clarity.
This however, also means that you have to implement these operators carefully. Otherwise when used in data structures like binary trees, the tree which is usually a template will assume that you’ve defined the comparator operators.
Why? That’s because binary trees sort things out naturally when you insert elements. It also uses the same algorithm to compare and proceed to the next relevant branch. (This reduces search times to O log ( n ) … )
It can also performs as a simple Set mechanism, rejecting elements that return true when the == operator is used between 2 keys or nodes.
Therefore, here’re the following to take note when you’ve decided to override and implement the comparator operators:
1) Make sure you implement ALL the comparator operators. Do not implement one without another.
2) Don’t try to use other return value type other than bool. I’m not sure if the compiler accepts it, but the comparator operators by default are meant to perform COMPARISON between TWO objects. Therefore it should be a diagnostic type of method, not a method that returns multiple possibilities.
3) Make sure your croc arrows are doing what they’re meant to do. Avoid trying stupid things like, > does smaller than instead of greater than.
4) Lastly but not least, JUSTIFY!! Always justify the need to implement these operators. Only do so when it is 100% justified. Do not implement for the sake of elegance. If you need, I’d rather you implement C++’s Big Three instead.
Next, I’d just throw in this little bonus about people who are bitching about operator overriding and overloading.
Come mon, stop bitching around! The ability to override operators like a god-granted priviledge granted to those who have the right skills to control their powers.
There’re some people who claims that people does stupid things with operator overrides, such as:
operator + as opposed to add()
Myth: Add method is clear and concise, it does the job and in a glance, prevents careless mistakes
Truth: Don’t you use operator + to add native types?
Myth: operator + can perform subtractions if there’s a mis-implementation.
Truth: What’s stopping someone from doing the same to add()?
Myth: operators make codes look unnecessarily confusing and hard to read
Truth: Get real. This problem can be easily resolved by placing of methods, event handler methods, operators, constructors and destructors properly. The same confusing problem arises if anyone is disorganized.
Myth: Overriding operators make codes unstable
Truth: A good C++ developer knows the dangers of overriding operators. Standard Template Library has done pretty well in that aspect.
Myth: Operator override introduces a different semantic into the header file, adding new things to learn.
Truth: These semantics were already there since a long long time ago. C++ is a standard for compilers to conform to. In this respect, one should be glad that C++ semantics are just that few and it’s not changed or added frequently.
So, that’s all I have to say for now. Always be careful when you touch operators. Don’t mess around with things that you cannot control or understand. (You may try though however…)
Regards.
Jeremy
- Permalink
- Admin
- 28 Apr 2009 10:16 PM
- Comments (0)