Question

Consider the following classes:

class Coord
{
public:
    double _x, _y;

    Coord(double x, double y)
    {
        _x = x;
        _y = y;
    }
};

class NamedPoint : public Coord
{
public:
    int _id;

    NamedPoint(int id, double x, double y) :
        Coord(x,y),
        _id(id)
    {
    }
};

I'd like to create a member function of NamedPoint -- coord() -- that returns a reference of type Coord corresponding to the NamedPoint.

For example, I'd like to something like:

const Coord& NamedPoint::coord()
{
    return ((Coord)*this);
}

But I get a warning about temporary variables and I'm not crazy about it.

Of course, the following works:

Coord coord()
{
    Coord c = *this;
    return c;
}

But I'd rather return a reference.

Does anyone know if this is possible using inherited classes?

Sorry for not explaining the point of the function. I'm overloading the == operator differently for Coord and NamedPoint. Coord would simply check {x,y} and NamedPoint would check {id,x,y}. If I forget to cast a NamedPoint to a Coord before this == test, I'll use the wrong version.

So, while I realize that

(Coord)np1 == (Coord)np2 

would give me what I want, I'd rather use something like

np1.coord() == np2.coord()

which I think is more clear as to what is going on.

Was it helpful?

Solution

What's the point of the function? NamedPoint is implicitly convertible to Coord anyway:

void foo(Coord& c)
{
    c._x = 5;
}

NamedCoord nc(0, 1, 2);
foo(nc); // c references the Coord part of nc

Anyway, your function should simply use this conversion:

const Coord& NamedPoint::coord()
{
    // Bad: takes the value of *this and slices off
    // the derived bits, leaving a temporary Coord.
    /* return ((Coord)*this); */

    // Good: takes the value of *this and refers
    // to the base bits, no temporaries.
    return *this;

    // (Same as:)
    /* return ((Coord&)*this); */
}

OTHER TIPS

@GMan gives the main solution.

However, it might be interesting to note in more detail the problem:

const Coord& NamedPoint::coord()
{
    return ((Coord)*this);
}

This is much the same as:

const Coord& NamedPoint::coord()
{
    Coord c = *this;
    return c;
}

Here it is clear that you are returning a reference to a temporary on the stack, which makes the reference to it useless, and hence the warning.

Now in the case presented, Coord is the base class and hence we have the simple solution given by @Gman.

In the general case, the principle is that if you want a reference to something, you better make sure that something will still be around.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top