Static variables, separate compilation

I wrote a program that was in one file and the methods were declared in the header. Initially, the program worked fine when it was in one file. But when I separated the program, I kept getting random entries for the destructor of one of the classes that was declared in the header file.

I have a static variable in my header to count the number of objects of a specific class. Whenever I create an object, I increment this variable. Then in my destructor I subtract 1 from that variable, check if it is 0 (which means the last object) and does something. Sometimes the value seems to be off, I don't know why. I have random calls in my application, but I don't understand why it would affect what I described above, thanks. Any help or understanding is appreciated!

[Update]: there is a base class that contains a destructor that is implemented in the header, then I have two derived classes that increment the static var in their constructor .. so what can I do?

What I am trying to do is the following: In my header, I have the following:

class A {
public:
    virtual ~A() {
        count --;
        if (count == 0) { /* this is the last one, do something */ }
    }

class B : public A {
public:
    B();
}

      

Then in class B I have

B::B() { 
    count++;
}

      

Where can I define an account so as not to be misleading? Thank.

0


source to share


4 answers


class A {
public:
    virtual ~A() {
        count --;
        if (count == 0) { // this is the last one, do something }
    }
protected:
    static int count;
};

class B : public A{
public:
B();
};

      

And then in one and only one of your source files, you need to put the following. It must be in the source file that contains the code for class A.



int A::count(0);

      

You need to do this because the header file declared that there would be a variable named count, but did not allocate any storage for it. If you didn't put it in the original file, the linker will complain that it was not found.

0


source


You must define a constructor in (all of them) to increase the count.

Note that if you don't define them, the compiler will automatically generate the following four methods:

  • Default constructor (unless another constructor is defined)
  • Default destructor
  • Copy constructor
  • Assignment operator

The following code overrides the compiler defaults, so you should get an accurate count.



 class A
 {
    static int count;

    public:
        A()   // Default constructor.
        {
            ++count;
        }
        A(A const& copy)  // Copy constructor/
        {                 // Note If you do not define it the compiler
            ++count;      // will automatically do it for you
        }
        virtual ~A()
        {
            --count;
            if (count == 0)
            {  // PLOP
            }
        }
        // A& operator=(A const& copy)
        // do not need to override this as object has
        // already been created and accounted for.
};

      

//// In the source file:

int A::count = 0;

      

+6


source


Where is your static variable defined? You may be accidentally defining it in a header file, and nesting is confusing things (and the compiler doesn't catch multiple definitions, which would be weird, but you never know).

Make sure the static class variable is defined with exactly one translation unit. You define it like this:

int MyClass::static_var;

      

This is where you put the initializer, if any.

+1


source


Can you elaborate on what you mean by "value seems to be off"? Do you have too many designs? Not enough destruction? If you have too many structures and not enough destruction, it will have nothing to do with static.

Also, what do you mean by static variable? Do you mean the static field of the element or the actual static variable?

If you only declare a static variable in a header (which I doubt you do), then every C file that includes that header will have a separate instance of that variable (since static in front of the global variable means it is restricted to that object) ...

0


source







All Articles