dimanche 15 novembre 2015

c++ variable/instance initializaiton order across different Translation units

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

Aucun commentaire:

Enregistrer un commentaire