Domanda

Considera le seguenti classi:

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)
    {
    }
};
.

Mi piacerebbe creare una funzione membro di NameDoint - coord () - che restituisce un riferimento di tipo coording corrispondente al nome del nome.

Ad esempio, vorrei qualcosa come:

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

Ma ottengo un avvertimento sulle variabili temporanee e non ne sono pazzo.

certo, i seguenti lavori:

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

Ma preferirei restituire un riferimento.

Qualcuno sa se questo è possibile usando lezioni ereditate?

Ci scusiamo per non spiegare il punto della funzione. Sto sovraccaricando l'operatore== in modo diverso per Coord e NamemedPoint. Coord, controllerebbe semplicemente {X, Y} e NameDoint controllerebbe {ID, X, Y}. Se dimentico di lanciare un nome Nomemedpoint a una coordinazione prima di questo test==, utilizzerò la versione sbagliata.

Quindi, mentre mi rendo conto che

(Coord)np1 == (Coord)np2 
.

mi darebbe quello che voglio, preferirei usare qualcosa come

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

che penso sia più chiaro su cosa sta succedendo.

È stato utile?

Soluzione

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); */
}

Altri suggerimenti

@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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top