q about globals inititialization order and solutions

Get answers to all your basic programming questions. No Ogre questions, please!
sergey akifiev
Kobold
Posts: 34
Joined: Mon Feb 09, 2004 7:56 am

q about globals inititialization order and solutions

Post by sergey akifiev »

another one simple q:
i have one program:

Code: Select all

//: C10:Out.cpp {O}
// First file
#include <fstream>
std::ofstream out("out.txt"); ///:~
//: C10:Oof.cpp
// Second file
//{L} Out
#include <fstream>
extern std::ofstream out;
class Oof {
public:
  Oof() { std::out << "ouch"; }
} oof;
int main() {} ///:~
it segfaults, as supposed, with "correct" :-) linking order
and another program:

Code: Select all

Mirror.h :
#ifndef MIRROR_H
#define MIRROR_H
class Mirror {
  bool b;
  Mirror* ptr;
 public:
  Mirror() {
    b = true;
    ptr = 0;
  }
  Mirror(Mirror* p) {
    b = false;
    ptr = p;
  }
  bool test() {
    if(ptr)
      return ptr->test();
    else
      return b;
  }
};
#endif // MIRROR_H

Mirror1.cpp :
#include "Mirror.h"
Mirror globalMirror;

Mirror2.cpp :
#include "Mirror.h"
extern Mirror globalMirror;
Mirror secondGlobalMirror(&globalMirror);
 ... and so on, totally of 5 files
MirrorMain.cpp : 
#include <iostream>
#include "Mirror.h"
using namespace std;
extern Mirror fifthGlobalMirror;
int main() {
  if(fifthGlobalMirror.test())
    cout << "true" << endl;
  else
    cout << "false" << endl;
}
but it doesn't work incorrectly (print false, instead of true), "ignoring" linking order.
or, may be, i wrote it wrong?
task was (taken from "Thinkig in C++" by Bruce Eckel):
31 In a header file, create a class Mirror that contains two data members: a pointer to a Mirror object and a bool. Give it two constructors: the default constructor initializes the bool to true and the Mirror pointer to zero. The second constructor takes as an argument a pointer to a Mirror object, which it assigns to the object’s internal pointer; it sets the bool to false. Add a member function test( ): if the object’s pointer is nonzero, it returns the value of test( ) called through the pointer. If the pointer is zero, it returns the bool. Now create five cpp files, each of which includes the Mirror header. The first cpp file defines a global Mirror object using the default constructor. The second file declares the object in the first file as extern, and defines a global Mirror object using the second constructor, with a pointer to the first object. Keep doing this until you reach the last file, which will also contain a global object definition. In that file, main( ) should call the test( ) function and report the result. If the result is true, find out how to change the linking order for your linker and change it until the result is false.
sergey akifiev
Kobold
Posts: 34
Joined: Mon Feb 09, 2004 7:56 am

Post by sergey akifiev »

and also, i don't know, how to implement next task:
33 Repair the problem in Exercise 32 using technique one shown in this book.
34 Repair the problem in Exercise 32 using technique two shown in this book.

theese techniques are: use of special initializer class and using of "wrapper" functions.
[edit]
for 33 i wrote something like that:

Code: Select all

#ifndef INITIALIZER_H
#define INITIALIZER_H
#include "Mirror.h"

extern Mirror globalMirror;
extern Mirror secondGlobalMirror;
extern Mirror thirdGlobalMirror;
extern Mirror forthGlobalMirror;
extern Mirror fifthGlobalMirror;

class Initializer {
  static int initCount;
  public:
  Initializer() {
    std::cout << "Initializer()" << std::endl;
    if(initCount++ == 0) {
      std::cout << "  performing initialization" << endl;

      // some init here. what should i put here?
    }
  }
}

static Initializer init;
#endif // INITIALIZER_H
but i don't know what to put for initialization of my globals?