11

I have a mistake I cannot understand when initializing member data in an inherited class with two different methods I thought they should be theoretically identical.

class gSolObject
    {
    public:
        gSolObject();
        virtual ~gSolObject(){}
        bool   isCollisionObject;
    };

class gPlanetObject : public gSolObject
    {
    public:
        gPlanetObject();
       ~gPlanetObject(){};
    };

gSolObject::gSolObject():isCollisionObject(1)
            {
            }

gPlanetObject::gPlanetObject():gSolObject(),isCollisionObject(0)
            {
            }

I get an error class 'gPlanetObject' does not have any field named 'isCollisionObject'.

However when I put the initialization right into the constructor's brackts {..} instead:

gPlanetObject::gPlanetObject():gSolObject()
            {
            isCollisionObject=0;
            }

It compiles fine. Why would that be?

EDIT: This also does not work

gPlanetObject::gPlanetObject():gSolObject(),gSolObject::isCollisionObject(0)

It writes 'expected class-name before '(' token'

CodeTrek
  • 435
  • 1
  • 3
  • 10
  • I don't think a duplicate? My class constructor is explicit? – CodeTrek Nov 12 '13 at 00:11
  • `class gPlanetObject : public gSolObject`, `gPlanetObject::gPlanetObject():gSolObject(),isCollisionObject(0)`. You're trying to initialize 'isCollisionObject' which is a member of the parent class. – kfsone Nov 12 '13 at 00:12
  • You're trying to initialize `gSolObject::isCollisionObject` in the constructor for a derived class `gPlanetObject`. Read the linked answer. – kfsone Nov 12 '13 at 00:15
  • ohh ok. I don't like that base class constructor.. it seems awkward.. in the other post reassignment is mentioned as problematic. Why is that? – CodeTrek Nov 12 '13 at 00:17
  • That's the solution you showed above as "compiles fine" (`isCollisionObject = 0;`) – kfsone Nov 12 '13 at 00:19
  • I know, but it is not good to do so? I have already used the code and going back would imply changing a lot of code if I want to implement a new baseconstructor.. – CodeTrek Nov 12 '13 at 00:20
  • @user2856452 as said in my edited answer, if the value is always the same, use default value instead of this – Thomas Ayoub Nov 12 '13 at 00:22
  • If it were always the same I would not have posted this question.. I need for each derived class a different variable to be inititalized, e.g. isCollisionObject, isFlyingObject etc. – CodeTrek Nov 12 '13 at 00:24

2 Answers2

13

You can't initialize member variables declared in base classes, because the base class constructor has already initialized them. All base constructors execute before member constructors.

You can reassign it. Or you can call a base class constructor that takes an argument and initializes its members with that value.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I read in the above duplicate post that reassignment is not good practice.. why is that? – CodeTrek Nov 12 '13 at 00:18
  • OK I decided to reassign, since nobody knows why this is bad practice... I am happy with it. thaks – CodeTrek Nov 12 '13 at 00:35
  • @user2856452: There are reasons to prefer the ctor-initializer list. Mostly for `const` objects, which can't be assigned, and expense of default-constructing some types, which doesn't apply to `bool`. – Ben Voigt Nov 12 '13 at 00:49
  • Good to know.. I have a lot of derived classes and they take different bool initializations than the base class. It would be hell to reassign. Also I find it difficult to read the ctor initializer list, I would get lost with several initializations in my derived classes. – CodeTrek Nov 12 '13 at 00:52
1

Edited : You can't call a method of a uninitialized object (here gSolObject) and that's why it works when you execute isCollisionObject(0) in the constructor. Furthermore, if you always set it to 0, then you should use default value in the gSolObject constructor.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142