1

Thanks in advance.

I saw these codes in some real project. I just simplified them to express my problem here. The base class puts the this pointer into the a vector(vec) in its constructor. Using this trick, we can leverlage the dynamic bonding to call the derived classes' method outside(in main func). The key point is to put the vector definition in Bash.h, and declaration in main.cpp.

My quesiton is, the output is not what I want. Why the vec is initialized and used in one Translation units(base.c, we can see the size is 1), then in other Translation units(main.c, we can see the size become 0), is intialized and cleared again? I want to know the intialization order accoross different Translation units. Seem that the Derive::dInstance is first, then vec is second, but why?

Base.h

#ifndef BASE_H
#define BASE_h

#include<iostream>
#include<vector>
using namespace std;
class Base{
    public:
        Base();
        virtual void speak();
};

#endif

Base.cpp

#include"Base.h"

vector<Base*> vec;
Base::Base() {
    vec.push_back(this);
    cout << "Base's constructor" << endl;
    cout << "Base() vector size: " << vec.size() << endl;**
}

void Base::speak() {
    cout << "I am Base" << endl;
}

Derive.h

#ifndef DERIVE_H
#define DERIVE_h
#include<iostream>
#include"Base.h"

class Derive: public Base {
    public:
        Derive();
        virtual void speak();

        static Derive dInstance;
};
#endif

Derive.cpp

#include "Derive.h"

// static member definition
Derive Derive::dInstance;

Derive::Derive() {
    cout << "Derived's construtor" << endl;**
}
void Derive::speak() {
    cout << "I am Derived" << endl;
}

main.cpp

#include<iostream>
#include"Base.h"

using namespace std;

extern vector<Base*> vec;
int main(int argc, char *argv[]) {
    cout << "vector size: " << vec.size() << endl;

    for(vector<Base*>::iterator iter = vec.begin(); iter != vec.begin(); iter++) {
        (*iter)->speak();
    }
}

Output:

Base's constructor
Base() vector size: 1
Derived's constructor
main() vector size: 0
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Edison
  • 31
  • 1
  • 3

2 Answers2

2

It's the static initialization order fiasco”.

The order of initialization between translation units of static (or global) variables is not defined. So think about what happens if the Derived.cpp file is initialized before Base.cpp, then you add to a vector that isn't initialized (constructed) leading to undefined behavior, then the vector is initialized.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks for your reply. But If I replace a vector with a variable(e.g. int a), repete the same stuff here, anything is fine. – Edison Nov 15 '15 at 12:48
-1

At first,there is no rule for the intialization order accoross different Translation units.

And, Global variable and global static variable will be initialized before main function. Local static variable which is belong to function FuncA() will be initialized at the first time the FuncA() is called.

Zhu Coding
  • 11
  • 1