2011-05-19 43 views
1

考虑下面的类:返回参照切​​片对象(超型)

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的成员函数 - 坐标() - 该返回对应于类型坐标的基准NamedPoint。

例如,我想是这样的:

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() 

我认为这是作为对正在发生的事情更清楚。

+0

你似乎没有注意到/承认转换为'Coord'的区别,它复制了对象的一部分,转换为'Coord&',它创建了对你的点的基类子对象的引用。 GMan的解决方案完成后者,你写的所有代码都会替代前者,这就是为什么你在第一个'coord()'函数中得到警告的原因。你说“我宁愿返回一个参考”,但是你返回了一个(部分)副本的引用,而不是原始的。然后'(Coord)np1 ==(Coord)np2' comparies也复制。无论你做什么,复制都是不必要的。 – 2011-05-19 00:39:07

+0

对不起,如果我不清楚。事实上,不同之处在于我首先提出这个问题的原因。我正在寻找一种方法来获得对基类子对象的引用(顺便说一句,这很好 - )我唯一能提出的解决方案就是创建子对象的副本。 – jedwards 2011-05-19 00:48:23

+0

不知道为什么这是downvoted。 – GManNickG 2011-05-19 08:25:06

回答

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

对不清楚这一点 - 它更像是一种“哲学”类型的东西 - 我相应地更新了我的问题。 – jedwards 2011-05-19 00:29:47

+0

谢谢 - 我不认为我知道铸造参考类型的语法(Coord&)。欣赏它。 – jedwards 2011-05-19 00:36:04

3

@GMan给出了主要的解决方案。

然而,这可能是有趣更详细地说明这个问题:

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

这是大致相同:

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

这清楚地表明,你正在返回参考一个临时的堆栈,这使得对它的引用无用,因此也是警告。

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

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

+0

谢谢,我原以为这是警告的意思。 – jedwards 2011-05-19 00:34:56