std::vector of references to derived class objects

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rsennat
    New Member
    • Dec 2007
    • 14

    std::vector of references to derived class objects

    Hi All,
    Here is the basic example of the using polymorphism. And then my question is below.
    Code:
     typedef std::vector<Vehicle*>  VehicleList;
     
     void myCode(VehicleList& v)
     {
       for (VehicleList::iterator p = v.begin(); p != v.end(); ++p) {
         Vehicle& v = **p;  // just for shorthand
     
         // generic code that works for any vehicle...
         ...
     
         // perform the "foo-bar" operation.
         v.fooBar();
     
         // generic code that works for any vehicle...
         ...
       }
     }
    ===================
     class Car : public Vehicle {
     public:
       virtual void fooBar();
     };
     
     void Car::fooBar()
     {
       // car-specific code that does "foo-bar" on 'this'
       ...  ← this is the code that was in {...} of if (v is a Car)
     }
     
     class Truck : public Vehicle {
     public:
       virtual void fooBar();
     };
     
     void Truck::fooBar()
     {
       // truck-specific code that does "foo-bar" on 'this'
       ...  ← this is the code that was in {...} of if (v is a Truck)
     }
    So, in this example, instead of std::vector<Veh icle*>, can I use std::vector<Veh icle> and still achieve the polymorphism, like calling the function of the derived class object reference it contains??

    Can you give an example of the same.

    Thanks
    rsennat
  • arnaudk
    Contributor
    • Sep 2007
    • 425

    #2
    C++ does not fully support the Liskov substitution principle; you can substitute the address of objects of derived classes in place of the base class pointer, but not derived objects themselves in place of a base class, so the answer to your question is: No.

    Some minor comments:
    line 6: Why not use a different local variable name to avoid confusion with the outer variable v?
    line 12: I would avoid the shorthand altogether and just use (*p)->fooBar();

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      You will not be able to use anyt Truck methods if you have a vector<Vehicle> .

      That's becuse the Truck-part of the object was sliced off when the the object was put in the vector.

      Polymorphism in C++ only works if you have a pointer or reference to the object.

      You should have a vector<Vehicle* >, or better, a vector of handles to Vehicle.

      Read this: http://bytes.com/forum/thread651599.html.

      Comment

      • rsennat
        New Member
        • Dec 2007
        • 14

        #4
        Originally posted by weaknessforcats
        You will not be able to use anyt Truck methods if you have a vector<Vehicle> .

        That's becuse the Truck-part of the object was sliced off when the the object was put in the vector.

        Polymorphism in C++ only works if you have a pointer or reference to the object.

        You should have a vector<Vehicle* >, or better, a vector of handles to Vehicle.

        Read this: http://bytes.com/forum/thread651599.html.
        Thanks for the information.
        And I have one more related query, if polymorphism works with reference to an object, then can we use like this, vector<Vehicle& >?

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Yes, you can.

          The essential thing here is that a Vehicle* or a Vehicle& do not require a copy of the object. Once that Truck is copied as a Vehicle, the Truck portion is sawed off. Technically, this is called slicing and it's usually a bad sign.

          Once you start using Vehicle* or Vehicle& in your vector, be sure those objects are always on the heap. That way you have control over deletion and not the compiler.

          It won;t be long after this that you will start using Handles to a Vehicle.

          And shortly after that, you will add a method to a Truck and you can't call it using a Vehicle* or Vehicle&. Therefore, you should design for a Visitor right up front. Read this: http://bytes.com/forum/thread674645.html.

          Comment

          • rsennat
            New Member
            • Dec 2007
            • 14

            #6
            Originally posted by weaknessforcats
            Yes, you can.

            The essential thing here is that a Vehicle* or a Vehicle& do not require a copy of the object. Once that Truck is copied as a Vehicle, the Truck portion is sawed off. Technically, this is called slicing and it's usually a bad sign.

            Once you start using Vehicle* or Vehicle& in your vector, be sure those objects are always on the heap. That way you have control over deletion and not the compiler.

            It won;t be long after this that you will start using Handles to a Vehicle.

            And shortly after that, you will add a method to a Truck and you can't call it using a Vehicle* or Vehicle&. Therefore, you should design for a Visitor right up front. Read this: http://bytes.com/forum/thread674645.html.
            Oh ok. Thanks a lot for all the information.

            Comment

            Working...