Guidelines or "rules of thumb" for overloading operators?, C/C++ Programming

Assignment Help:

What are some guidelines / "rules of thumb" for overloading operators?

A: Here are a few guidelines / rules of thumb .Use common sense. If your overloaded operator makes life simpler and safer for your users, do it; or else don't. It is the most significant guideline. Actually it is, in a very real sense, the only guideline; the rest are merely special cases.

If you describe arithmetic operators, maintain usual arithmetic identities. For instance, if your class describe x + y and x - y, then x + y - y have to return an object which is behaviorally equivalent to x. The term behaviorally equivalent is described in the bullet on x == y below, although simply put, this means the two objects must ideally act like they have the similar state. It should be true even if you decide not to define an == operator for objects of your class.

You must provide arithmetic operators only while they make logical sense toward the users. Subtracting two dates makes sense, logically returning the duration among those dates, so you may want to let date1 - date2 for objects of your Date class (provided you have a reasonable class/type to signify the duration among two Date objects). Though adding two dates makes no sense: what does it mean to add July 4, 1776 with June 5, 1959? Likewise it makes no sense to multiply or divide dates, thus you should not define any of those operators.

You must provide mixed-mode arithmetic operators only while they make logical sense to users. For instance, this makes sense to add duration (e.g. 35 days) to a date (e.g. July 4, 1776), thus you might define date + duration to return a Date. Likewise date - duration could also return a Date. However duration - date does not make sense at the conceptual level (what does this mean to subtract July 4, 1776 from 35 days?) so you must not define that operator.

If you give constructive operators, they must return their result by value. For instance, x + y must return its result by value. If this returns by reference, you will possibly run into many problems figuring out who owns the referent and while the referent will get destructed. Of no importance if returning by reference is more competent; it is perhaps wrong.

If you provide constructive operators, they must not change their operands. For instance, x + y must not change x. For some crazy cause, programmers frequently define x + y to be logically the similar as x += y since the latter is faster. But keep in mind, your users expect x + y to make a copy. Actually they selected the + operator (over, say, the += operator) exactly since they wanted a copy. If they wished to modify x, they would have utilized whatever is equivalent to x += y instead. For your users don't make semantic decisions; it's their decision, not yours, whether they wish the semantics of x + y vs. x += y. Tell them that one is faster if you wish, but then step back and allow them make the last decision they know what they're trying to get and you do not.

If you provide constructive operators, they ought to let promotion of the left-hand operand. For instance, if your class Fraction supports promotion from int to Fraction (using the non-explicit ctor Fraction::Fraction(int)), and if you let x - y for two Fraction objects, you ought to also let 42- y. In practice it simply means that your operator-() must not be a member function of Fraction. You will make it a friend typically, if for no other cause than to force it into the public: part of the class, but even if it is not a friend, it must not be a member.

Generally, your operator must change its operand(s) if and only if the operands get changed while you apply the similar operator to intrinsic types. x == y and x << y must not change either operand; x *= y and x <<= y must (but only the left-hand operand).

If you define x++ & ++x, maintain the usual identities. For instance, x++ & ++x should have should have the same observable effect on x, and ought to differ only in what they return. ++x ought to return x by reference; x++ ought to either return a copy (by value) of the original state of x or must have a void return-type. Usually you're better off returning a copy of the original state of x by value, especially if your class will be utilized in generic algorithms. The easy way to do that is to implement x++ by three lines: make a local copy of *this, call ++x (that means. this- >operator++()), then return local copy. Similar comments for x-- and --x.

If you define ++x and x += 1, maintain the usual identities. For instance, these expressions should have the same observable behavior, by including the same result. Among other things, that means your += operator must return x by reference. Alike comments for --x and x -= 1.

If you define *p and p[0] for pointer like objects, maintain the usual identities. For instance, these two expressions must have the same result and neither must change p.

If you define *(p+i) and p[i] for pointer-like objects, maintain the usual identities. For instance, these two expressions must have the same result and neither must change p. Similar comments for p[-i] and *(p-i).

Generally Subscript operators come in pairs; see on const-overloading.

If you define x == y, then x == y must be true if and only if the two of objects are equivalent behaviorally. In this bullet, the term "behaviorally equivalent" refers to the observable behavior of any operation or sequence of operations applied to x will be the similar as when applied to y. The term "operation" means methods, operators, and friends or just regarding anything else you can do with these objects (except, certainly the address-of operator). You won't always be capable to achieve that aim, but you have to get close, and you should document any variances (other than the address-of operator).

If you define x == y & x = y, maintain the usual identities. For instance, after an assignment, the two objects must be equal. Even if you don't define x == y, the two objects should be behaviorally equivalent (see above for the meaning of that phrase) after an assignment.

If you define x == y and x != y, you mustg maintain the usual identities. For instance, these expressions must return something convertible to bool, neither must change its operands, and x == y must have the similar result as !(x != y), and vice versa.

 

If you define inequality operators such as x <= y and x < y, you must maintain the usual identities. For instance, if x < y & y < z are both true, then x < z must also be true, etc. Same comments for x >= y and x > y.

If you define inequality operators such as x < y and x >= y, you must maintain the usual identities. For instance, x < y must have the result as !(x >= y). You can't always do that, however you must get close and you must document any variances. Same comments for x > y and !(x <= y), etc. Ignore overloading short-circuiting operators: x || y or x && y. The overloaded versions of these don't short-circuit they evaluate both of the operands even if the left-hand operand "determines" the outcome, so it confuses users.

Ignore overloading the comma operator: x, y. overloaded comma operator does not contain the similar ordering properties that it has while it is not overloaded, & that confuses users.

Don't overload an operator that is non-intuitive to your users. It is called the Doctrine of Least Surprise. For instance, altough C++ uses std::cout << x for printing, & although technically printing is called inserting, and even though inserting sort of sounds like what happens while you push an element on a stack, don't overload myStack << x to push an element on a stack. It may make sense while you're really tired or otherwise mentally impaired, and a few of your people might think it's "kewl," however just say No.

Use common sense. If you don't view "your" operator listed here, you can figure it out. Just keep in mind the ultimate goals of operator overloading: to make life easier for your users, particularly to make their code cheaper to write and more obvious.

Caveat: the list is not exhaustive. This means there are other entries that you might consider

"missing."

Caveat: the list contains guidelines, not hard and fast rules. This means almost every entry has exceptions, and most of those exceptions are not explicitly stated.


Related Discussions:- Guidelines or "rules of thumb" for overloading operators?

Call by reference, Call by reference: Arguments to a function can be pa...

Call by reference: Arguments to a function can be passed in two way; one by call by value and other by call by reference.  Call by value is passed either through a constant

What are control structures, What are control structures? - Control str...

What are control structures? - Control structures decide which instructions in program must be executed. - This implies that program flow may not necessarily move from one s

Operations on strings, 1 Aims The main purpose of the assignment is to ...

1 Aims The main purpose of the assignment is to let you practice the following programming techniques: perform operations on pointers to basic and more complex types;

Explain the working of array with strings, Explain the working of Array wit...

Explain the working of Array with Strings? A string is defined in C language as an array of characters. A null character (‘\0') is automatically added to the end of the charact

Program for dynamic 2d memory, Requirements: 1.  This assignment as well...

Requirements: 1.  This assignment as well as other assignments in this class must be finished on Windows operating system. 2.  Zip your program and submit the zip file on ANG

Padovan string., #question.A Padovan string P(n) for a natural number n is ...

#question.A Padovan string P(n) for a natural number n is defined as: P(0) = ‘X’ P(1) = ‘Y’ P(2) = ‘Z’ P(n) = P(n-2) + P(n-3), n>2 where + denotes string concatenation. For a s

C program for rotation, Normal 0 false false false EN-U...

Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

How to implement tr- 069 protocol, Description - The TR-069 CPE WAN Managem...

Description - The TR-069 CPE WAN Management Protocol (CWMP) is a protocol that was created by the Broadband Forum (formally the DSL Forum) which sets out a common method for CPE de

Write Your Message!

Captcha
Free Assignment Quote

Assured A++ Grade

Get guaranteed satisfaction & time on delivery in every assignment order you paid with us! We ensure premium quality solution document along with free turntin report!

All rights reserved! Copyrights ©2019-2020 ExpertsMind IT Educational Pvt Ltd