views:

881

answers:

4

If I have something like

class Base {
 static int staticVar;
}

class DerivedA : public Base {}
class DerivedB : public Base {}

Will both DerivedA and DerivedB share the same staticVar or will they each get their own?

If I wanted them to each have their own, what would you recommend I do?

+5  A: 

They will each share the same instance of staticVar.

In order for each derived class to get their own static variable, you'll need to declare another static variable with a different name.

You could then use a virtual pair of functions in your base class to get and set the value of the variable, and override that pair in each of your derived classes to get and set the "local" static variable for that class. Alternatively you could use a single function that returns a reference:

class Base {
    static int staticVarInst;
public:
    virtual int &staticVar() { return staticVarInst; }
}
class Derived: public Base {
    static int derivedStaticVarInst;
public:
    virtual int &staticVar() { return derivedStaticVarInst; }
}

You would then use this as:

staticVar() = 5;
cout << staticVar();
Greg Hewgill
(Note that the CRTP also allows derived class to get their own version of some static variable.)
sbi
I think I'll go with the virtual functions, but just to clarify, if I declare a static variable with the same name in a derived class, it will basically override the base class right? So I can count on its existance in all derived classes...
Mark
You can in fact declare a static variable with the same name in a derived class. If you do this, I would qualify each reference to that variable with its class name, ie: `virtual int }`
Greg Hewgill
+1  A: 

They will share the same instance.

You'll need to declare separate static variables for each subclass, or you could consider a simple static map in which you could store variables that are referenced by derived classes.


Edit: A possible solution to this would be to define your base class as a template. Having a static variable defined in this template would mean that each derived class will have it's own instance of the static.

Alan
+1 for the template idea.
Greg Hewgill
In this case, by "derived" you mean Base<A> would have a different static var than Base<B>, but Derived<A> would still share with Base<A> no?
Mark
There is no template called `Derived`. Instead, in this case, it's `template<typename> struct Base { static int staticVar; protected: ~Base() { } }; template<typename D> int Base<D>::staticVar; struct DerivedA : Base<DerivedA> { }; struct DerivedB : Base<DerivedB> { };`. Now there are two static variables, which you can access with `DerivedB::staticVar` and `DerivedA::staticVar`
Johannes Schaub - litb
A: 

There is only one staticVar in your case: Base::staticVar

When you declare a static variable in a class, the variable is declared for that class alone. In your case, DerivedA can't even see staticVar (since it's private, not protected or public), so it doesn't even know there is a staticVar variable in existence.

Reed Copsey
A: 

To ensure that each class has it's own static variable, you should use the "Curiously recurring template pattern" (CRTP).

template <typename T>
class Base
{
    static int staticVar;
};

template <typename T> int Base<T>::staticVar(0);

class DerivedA : public Base<DerivedA> {};
class DerivedB : public Base<DerivedB> {};
Mark Ingram