NoOdle
NoOdle

Reputation: 85

What does operator float*() do?

I have been looking through source code trying to learn more about C++ and I came across some code that looked confusing. I haven't been able to figure out its use by playing around with it.

Please can someone explain what the operator float *() does and how it is used?

class Vector
{
public:
    float x,y,z;

Vector() : x(0), y(0), z(0){ } Vector( float x, float y, float z ) : x(x), y(y), z(z){ } operator float*(){ return &x; } operator const float *(){ return &x; }

I have searched StackOverflow and it looks like it is a conversion operator but I am still unsure what it actually does and why it is useful.

Kind regards,

Upvotes: 4

Views: 9035

Answers (3)

Konrad Rudolph
Konrad Rudolph

Reputation: 545598

operator type_name declares an implicit conversion operator. In other words, this function is called when you are attempting to (implicitly) convert an object of your type to float* – for instance in an assignment:

Vector x(1, 2, 3);
float* f = x;
assert(*f == 1);

Needless to say, this particular conversion is quite terrible because its effect is pretty unintuitive and easily results in impossible to find bugs. Implicit conversions should generally be handled with care since they hide potentially confusing semantics. But they can be used well with types which are supposed to be used interchangeably, and where a conversion doesn’t hurt.

For instance, consider the case where you write your own integer and complex classes. A conversion from integer to complex is harmless, since every integer is a complex number (but not vice-versa). So having an implicit conversion integercomplex is safe.

Upvotes: 10

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

As it was said it is a conversion operator that converts an object of type Vector to an object of type float *. This conversion operator can be called implicitly because it has no function specifier explicit.

I think that the idea of introducing this operator was to access data members x, y, z as an array of floats. In this case you could apply some standard algorithms to an object of the class converting it to an array of floats.

Take into account that the second overloaded operator-function shall have qualifier const.

Consider the following code

#include <iostream>
#include <algorithm>


class Vector
{
public:
    float x,y,z;



    Vector() : x(0), y(0), z(0){
    }

    Vector( float x, float y, float z ) : x(x), y(y), z(z){
    }

    operator float*(){
        return &x;
    }

    operator const float *() const {
        return &x;
    }
};

int main() 
{
    Vector v( 1, 3, 2 );
    auto max = std::max_element( v + 0, v + 3 );
    std::cout << *max << std::endl;

    return 0;
}

The output is 3.

Take into account that according to the C++ Standard

13 Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object

So the order of the data members of the class is defined.

Upvotes: 7

Dennis
Dennis

Reputation: 3731

It's a conversion operator allowing the class to be used with APIs that want a float*.You have two different versions because one will convert the class to a const float* and the other to a non-const. The non-const conversion operator breaks your class's encapsulation though.

Usefulness: Well it can be very handy when, as I mentioned, you want to work with a library that expects a certain type. It can also be useful when there is a natural conversion between two types.

Upvotes: 3

Related Questions