views:

118

answers:

3

Hello there. I have a set of code, which mimics a basic library cataloging system. There is a base class named items, in which the the general id,title and year variables are defined and 3 other derived classes (DVD,Book and CD).

Base [Items]

Derived [DVD,Book,CD].

The programs runs, however I get the following warnings, I'm not sure how to fix these.

>"C:\Program Files\gcc\bin/g++"  -Os -mconsole -g -Wall -Wshadow -fno-common mainA4.cpp -o mainA4.exe
In file included from mainA4.cpp:5:
a4.h: In constructor `DVD::DVD(int, std::string, int, std::string)':
a4.h:28: warning: `DVD::director' will be initialized after
a4.h:32: warning:   base `Items'
a4.h:32: warning:   when initialized here
a4.h: In constructor `Book::Book(int, std::string, int, std::string, int)':
a4.h:48: warning: `Book::numPages' will be initialized after
a4.h:52: warning:   base `Items'
a4.h:52: warning:   when initialized here
a4.h: In constructor `CD::CD(int, std::string, int, std::string, int)':
a4.h:66: warning: `CD::numSongs' will be initialized after
a4.h:70: warning:   base `Items'
a4.h:70: warning:   when initialized here
>Exit code: 0
+7  A: 

When you declare member variables in a class, they're initialized in the order you declare them. But you may write them in any order in your constructor's initializer list. For example,

struct foo {
   int a;
   int b;

   foo(): b(5), a(3) {}
};

will construct a and then b, even though it appears that you're initializing them in the other order.

The compiler issues a warning because you can trick yourself into writing incorrect code. For example,

struct foo {
    int a;
    int b;

    foo(): b(5), a(b) {}
};

the value of a will be undefined.

Jesse Beder
Thank you very much
sil3nt
+1  A: 

When you initialize class members in the constructor, initialize them in the same order in which they are declared. E.g.:

class Foo {
  public:
    int a;
    int b;
    Foo() : a(0), b(0) {}
};

In Foo() constructor, switching the order of a and b would lead to your warnings. Same goes for initializing the base classes (whose constructors, if called explicitly, should be called before any data member initializers).

DS
+4  A: 

You need to take a look at your constructors and member initialization lists. It is tricky to tell without seeing the code, but what is happening is that you have code like this:-

class my_class : public base1, public base2
{
    public:
        my_class();

    private:
        member1 member1_;
        member2 member2_;
}

my_class::my_class() 
    : member2_(...)
    , member1_(...)
    , base2_(...)
    , base1_(...)
{ }

This will produce similar warnings. The reason is that in C++ the constructor always constructs the base classes in the order shown in the base class list (base1 followed by base2), then it constructs the member variables from top to bottom in the class definition. It does this without regard for the order you specify things in your member initialization list - this order is ignored, but if it doesn't match some compilers (including yours it seems) will warn you about it.

The reason it does this by the way is that C++ has a strict requirement that destructors be called in the reverse order of constructors, so if it did things in the order of the member initialization lists it would have to somehow "remember" which constructor had been called so that it could call the destructors in the right order. It doesn't do this, but instead just always uses the same order.

Stewart