For ease I will split this section into relational operators and arithmetic operators. We can represent the relational operators using the following diagram

These operators will always return a boolean value which will be the result of some form of comparison.

Arithmetic operators will return an object of some type which depending upon the context may be either the same object or a new type of object. Later we will also add the += style operators which will mutate the current object rather than returning a value.

**Equality Operators**

In the case of the Vec3 class there are only two equality operator which make sense to implement, these are the == and != operators. Also we must ensure that we are doing correct comparison as we are storing floating point values. ( see here for an in depth discussion of floating point comparison ). For this example I'm going to generate a very simple FCompare macro which will be used to do a comparison via a simple epsilon error value.

//---------------------------------------------------------------------------------------------------------------------- /// @brief define EPSILON for floating point comparison //---------------------------------------------------------------------------------------------------------------------- #ifndef EPSILON const float EPSILON = 0.001f; #endif //---------------------------------------------------------------------------------------------------------------------- /// @brief FCompare macro used for floating point comparison functions //---------------------------------------------------------------------------------------------------------------------- #define FCompare(a,b) \ ( ((a)-EPSILON)<(b) && ((a)+EPSILON)>(b) )In the first example I will produce a "Member operator" for the equality operator, first in the .h file we declare the operator

bool Vec3::operator==(const Vec3 &_rhs) { return FCompare(m_x,_rhs.m_x) && FCompare(m_y,_rhs.m_y) && FCompare(m_z,_rhs.m_z); }As you can see in this case we do a component wise FCompare with the current object and the rhs value. We can test this using the following code from the previous examples

if(b==c) std::cout<<"b==c is true\n"; else std::cout<<"b!=c \n"; if(a==fromFloat) std::cout<<"a==fromFloat\n"; else std::cout<<"a!=fromFloat\n";Which gives the following output

testing equality operators b==c is true a!=fromFloatTo generate the != method we do the following

/// in .h /// @brief != operator bool operator!=(const Vec3 &_rhs); /// in .cpp bool Vec3::operator!=(const Vec3 &_rhs) { return !(*this==_rhs); }For the free function operator we have to write some additional code again to allow the free function access to the attributes. In this case we are going to write a method called isEqual ( note that my coding standard says this kind of method should be formed as a question as it returns a bool)

/// @brief function to test equality bool isEqual(const Vec3 &_rhs) const;The actual code for this class method will use the same FCompare macro as above and looks like this

bool Vec3::isEqual(const Vec3 &_rhs) const { return FCompare(m_x,_rhs.m_x) && FCompare(m_y,_rhs.m_y) && FCompare(m_z,_rhs.m_z); }The free function definitions of the == and != methods are now declared outside of the class but still in the .h file as follows

/// @brief free operator for equality testing bool operator ==(const Vec3 &_lhs, const Vec3 &_rhs); /// @brief free operator for equality testing bool operator !=(const Vec3 &_lhs, const Vec3 &_rhs);Finally we write the main function code, not that as they are no longer class methods it is no longer valid to mark the methods as const (in fact you get the following error with g++ error: non-member function 'bool operator==(const Vec3&, const Vec3&)' cannot have cv-qualifier )

bool operator ==(const Vec3 &_lhs, const Vec3 &_rhs) const { return _lhs.isEqual(_rhs); } bool operator !=(const Vec3 &_lhs, const Vec3 &_rhs) { return !_lhs.isEqual(_rhs); }

## No comments:

## Post a Comment