2011-02-28 70 views
4

假设你有以下对象层次结构:C++为什么不是第二个表达式有效?

class Vehicle { 
public: 
    virtual ~Vehicle() {} 
}; 
class LandCraft: public Vehicle {}; 
class Truck: public LandCraft {}; 

现在,我们有两个表达式:

Truck truck; 
Vehicle& vehicle = truck; 

根据解决一门功课,第二个表达式是无效的。但为什么?我的编译器根本没有抱怨,而且我也没有看到这里应该出现什么问题。

+0

哪个编译器?你是否尝试过“pedantic”标志(或同等标志)? – suszterpatt 2011-02-28 16:12:19

+0

对我来说似乎也是正确的,因为通过使用对“Vehicle”的引用避免了“切片”问题(http://stackoverflow.com/questions/2822146/references-and-the-slicing-problem)。 – James 2011-02-28 16:13:27

+0

看起来不错。这个问题是否真的使用'车辆&'?如果它只是使用'车辆',那么你会有切片问题。 – 2011-02-28 16:13:41

回答

6

这听起来像家庭作业的解决方案是不正确的。从派生实例初始化对基类型的引用没有任何问题。

编辑

正如一些人所指出的那样(Slaks特别),而有什么不对这个说法本身,它为未来的道路发生错误的可能性。它允许你任意地将任何Vehicle放置到期望Truck的地方。例如考虑以下内容

Truck truck; 
Vehicle& reallyATruck = truck; 
reallyATruck = LandCraft(); 

哎呀!

+0

我没有看到任何不安全的地方。这只是一个切片问题,与引用无关,只是多态。 – GManNickG 2011-02-28 19:55:31

1

第二个表达式完全有效。您可能会误解解决方案所说的内容。也许这并不是说它在语法上是无效的,但有其他一些问题。

当你正在使用的课程没有虚拟功能时,看起来有点奇怪和可疑。

我的倾向是,作业解决方案只是错误的。但是让它变得如此简单的错误似乎很奇怪。

1

对不起,但我已经验证您的代码在Visual Studio 2010中运行良好,除了您在类Vehicle的末尾错过了分号。

1

SLaks已经解释了为什么表达不安全,但它是合法的。

根据Comeau的说法,唯一的错误是在class Vehicle {} /* HERE */末尾丢失分号。

+0

我的答案是否正确? – SLaks 2011-02-28 16:20:55

+0

@SLaks:在您编辑之后它是正确的,我希望人们开始扭转他们的低估。 – 2011-02-28 16:22:20

+0

该表达式不是以任何方式不安全的,事实上它在变元传递中被广泛使用。事实上,你可以切分不同类型的对象(SLaks演示)与表达无关。并且要说清楚,我只是在编辑之后阅读SLaks的答案,并因为这个特殊原因而低估了答案。 – 2011-02-28 17:12:35

相关问题