返回对切片对象的引用(超类型)

时间:2011-05-19 00:13:16

标签: c++ inheritance reference object-slicing

考虑以下课程:

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

我想创建NamedPoint的成员函数--coord() - 返回与NamedPoint对应的Coord类型的引用。

例如,我想要像:

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

但我收到关于临时变量的警告,我对此并不感到高兴。

当然,以下工作:

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

但我宁愿返回一个参考文献。

有没有人知道使用继承类是否可行?

很抱歉没有解释该功能的要点。我为Coord和NamedPoint以不同的方式重载了==运算符。 Coord只需检查{x,y},NamedPoint将检查{id,x,y}。如果我忘记在此==测试之前将一个NamedPoint强制转换为Coord,我将使用错误的版本。

所以,虽然我意识到了

(Coord)np1 == (Coord)np2 

会给我我想要的东西,我宁愿使用像

这样的东西
np1.coord() == np2.coord()

我认为更清楚的是发生了什么。

2 个答案:

答案 0 :(得分:7)

这个功能有什么意义?无论如何,NamedPoint可以隐式转换为Coord

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

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

无论如何,你的功能应该只使用这个转换:

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

答案 1 :(得分:3)

@GMan提供主要解决方案。

但是,更详细地说明这个问题可能会很有趣:

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

这与以下内容大致相同:

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

很明显,你在堆栈上返回一个临时引用,这使得对它的引用变得无用,从而发出警告。

现在在提供的案例中,Coord是基类,因此我们有@Gman给出的简单解决方案。

在一般情况下,原则是如果您想要引用something,最好确保something仍然存在。