Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it considered good design to compare objects of different types?

Would you consider this evidence of bad design?

//FooType and BarType not in the same hierarchy
bool operator==(const FooType &, const BarType &);
bool operator<(const FooType &, const BarType &);

For example, if FooType is double measuring seconds since epoch and BarType is a tuple of three integers (year, month, and day) providing date in UTC, comparisons like above "make sense".

Have you seen such inter-type comparisons? Are they frowned upon in the C++ community?

like image 861
roger.james Avatar asked Jul 02 '13 20:07

roger.james


People also ask

How do you compare two objects?

The equals() method of the Object class compare the equality of two objects. The two objects will be equal if they share the same memory address. Syntax: public boolean equals(Object obj)

Is a function to comparing the objects?

Comparing objects is easy, use === or Object.is(). This function returns true if they have the same reference and false if they do not.

How many ways can you compare two objects in JavaScript?

JavaScript provides 3 ways to compare values: The strict equality operator === The loose equality operator == Object.is() function.


Video Answer


2 Answers

To start with, there's nothing wrong with using free functions instead of member functions, in fact it's recommended practice. See Scott Meyer's How Non-Member Functions Improve Encapsulation. You'll want to provide the comparisons in both directions though:

bool operator==(const FooType &, const BarType &);
bool operator==(const BarType &, const FooType &);

Second, it's perfectly acceptable to provide these comparisons if the comparisons make sense. The standard library for example allows you to compare std::complex values for equality with floating point, but not less-than.

The one thing you want to avoid is comparisons that don't make sense. In your example one of the time values is a double, which means the comparison would occur for any floating point or integer value once you take standard promotions into account. This is probably more than you intended since there's no way to determine if any particular value represents a time. The loss of type checking means that there's a potential for unintended bugs.

like image 85
Mark Ransom Avatar answered Oct 14 '22 09:10

Mark Ransom


Personal vision and experience

I personally do not frown upon the comparison between different types. I even encourage it, as it may improve code readability; making what you are doing seem more logical. Outside of the basic number types, and maybe a string and a character, I find it hard to give you a logical intra-type comparison, and I don't remember having met many. I have met alot of arithmetic operators used like this though.

How to use them

You should be careful with what you are doing, they are used scarcely for a reason. If you offer a function for the comparison of two different types, the outcome should be logical and what the user intuitively expected. It is also desirelable to write good documentation for it. Mark Ransom already said it, but it is good if users can compare in both directions. If you think your comparison is not sufficiently clear enough with an operator, you should think about using a named function. This is also a very good solution if your operator can have multiple meanings.

What can go wrong

You do not have full control over what the user will do with what you have written. tletnes gave a good example of this, where two integers are compared, but the outcome has no meaning. In contradiction to this, the comparison of two different types can be very right. A float and an integer both representing seconds, can be well compared.

Arithmetic operators

Next to logical, I would like to show an intra-type example with arithmetic operators. Arithmetic operators are much like logical operators when talking about intra-type usage.

Say you have an operator + for a two dimentional vector and a square. What does this do? The user might think it scales the square, but another user is sure it translates! These kinds of issues can be very frustrating to your users. You can solve this by providing good documentation, but what I personally prefer, is specifically named functions, like Translate.

Conclusion

Intra-type logical operators can be useful and make clean code, but bad usage makes everything just more complicated.

like image 33
Aart Stuurman Avatar answered Oct 14 '22 09:10

Aart Stuurman