1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2001
    Rep Power

    Default constructor needed to use vector


    I have a hierarchy of Actions (NonMovingActions and MovinActions each with sub-hierarchies). Actions class has an abstract function.

    class Action
    	Action(Agent& agent, ...):agent(agent),..{}
    	virtual ~Action(void);
    	virtual bool run()=0;
    Now I need to store all actions into a single vector:

    class Agent
        Agent(World& world);
        virtual ~Agent(void);
       vector<Action> actions;
       unsigned int actionIterator;
    It appears that C++ does not allow this (in Java it was possible). Compiler objects that Action class is abstract (and cannot be instantiated?!)

    error C2259: 'Action' : cannot instantiate abstract class
    1- May I know what do I not understand here? We cannot refer to sub-class instances with a reference of parent class type?

    2- Should I use vector of pointers instead or what?

    I appreciate your time and help.

  2. #2
  3. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Alpharetta, GA
    Rep Power
    Short answer: declare actions as a vector of pointer to Action.
        vector<Action*> actions;
    Long answer:
    The difference between what you are familiar with in Java, and what you are getting now in C++, is that in Java, object variables are always references to objects, whereas in C++, they are concrete structures - the object itself, rather than a pointer or handle referring to it. If you try to create a variable of an abstract class - as opposed to a pointer to said class - you get an error, as there is no concrete implementation for some of the methods of that class, meaning that there is nothing to go in the VTABLE (the internal table that keeps track of which virtual methods go with which classes). Furthermore, since the object is a fixed structure, it cannot be assigned a value from an object of a child class, as it does not have memory set aside for all of the members of the child class.

    This is the same reason why upcasting an object to a parent class (again, as opposed to a pointer to the child object) can cause loss of data - the parent class doesn't actually have all of the 'slots' or spaces for the data members, so any added data members get lost in the upcast.

    Note, however, that pointers to a class are not the same type as objects of said class. Thus, you can declare a pointer to an abstract class, and it will gladly accept a pointer to any child classes of the class it points to.

    This is also related to why, if you are to use methods polymorphically from a pointer to a parent class, that method must be declared as virtual. By default, the compiler creates a fixed reference to a method for a given class and its pointers, which is used whenever the method is called, regardless of whether or not the actual object is of that class or a child class. By declaring the method virtual, the compiler then knows that it needs to check the VTABLE of the object itself and make an indirect call, rather than having a simple fixed function call.

    Comments on this post

    • Lux Perpetua agrees
    Last edited by Schol-R-LEA; June 6th, 2012 at 02:26 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov

IMN logo majestic logo threadwatch logo seochat tools logo