4

Suppose you have the following object hierarchy:

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

Now, we have the two expressions:

Truck truck;
Vehicle& vehicle = truck;

According to a solution to a homework, the second expression is not valid. But why? My compiler doesn't complain at all, and I don't see what should be wrong here.

The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156
helpermethod
  • 59,493
  • 71
  • 188
  • 276

4 Answers4

6

It sounds like the homework solution is incorrect then. There is nothing wrong with initializing a reference to a base type from an instance of a derived.

EDIT

As several people have pointed out (Slaks in particular) while there is nothing wrong with this statement in itself, it does provide the potential for future errors down the road. It allows you to arbitrarily put any Vehicle into a place which expects a Truck. For example consider the following

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

Whoops!

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I don't see anything unsafe here. That's just a slicing issue and has nothing to do with references, just polymorphism. – GManNickG Feb 28 '11 at 19:55
1

The second expression is perfectly valid. You may be misinterpreting something the solution is saying. Maybe it's not saying it's syntactically invalid, but has some other problem.

It does seem a little odd and suspicious to do that when the classes you're working with have no virtual functions.

My inclination is that the homework solution is just flat out wrong. But it seems odd for it to get something so simple wrong.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
1

Sorry, but I have verified that your codes works well in Visual Studio 2010, except you missed a semicolon at the end of class Vehicle.

wenqiang
  • 954
  • 1
  • 5
  • 14
1

SLaks has explained why that expression isn't safe, but it is legal.

According to Comeau, the only error is a missing semicolon on the end of class Vehicle {} /* HERE */.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • @SLaks: after your edit it's correct, and I would hope that people start reversing their downvotes. – Ben Voigt Feb 28 '11 at 16:22
  • The expression is not unsafe by any means, and in fact is very widely used in argument passing. The fact that you can slice a different type of object (which SLaks demonstrated) is unrelated to the expression. And to make it clear, I have only read SLaks answer after the edit and downvoted for this particular reason. – David Rodríguez - dribeas Feb 28 '11 at 17:12
  • @David: As I commented on SLaks answer, references and pointers are safely covariant only when the target is `const` (considering the pointer, not the object). Read-only interfaces are covariant, write-only interfaces are contravariant. – Ben Voigt Feb 28 '11 at 20:09