Question

i'm trying to provide different static initializations for classes in a hierarchy, but when i tried with this code:

#include <iostream>

using namespace std;

struct base {
static const char* componentName;
};
const char* base::componentName = "base";

struct derived : public base {};

const char* derived::componentName = "derived";

int main() {

cout << base::componentName << endl;
cout << derived::componentName << endl;
}

I ended up with this build error:

test.cpp:15: error: ISO C++ does not permit ‘base::componentName’ to be defined as ‘derived::componentName’
test.cpp:15: error: redefinition of ‘const char* base::componentName’
test.cpp:11: error: ‘const char* base::componentName’ previously defined here

It seems that static initializations cannot be overriden on the derived classes? If this does not work i might always define the componentName to be a static function that returns a const char*, the only problem with that i was sort of hoping to do initializations for partial specializations, and there does not seem to be any way that i know of to redefine just a single function in a partial specialization, without copying all the other code that will remain mostly the same

Was it helpful?

Solution

You need to declare it in your subclass too.

struct derived : public base {
    static const char* componentName;
};

OTHER TIPS

A static member variable means there is a single variable that's shared across all instances of that class. Trying to have one value for the base class and a different value for the derived class doesn't work because they're both sharing the same variable, which (obviously enough) can't simultaneously be set to two different values.


I think the reason is really because the following is true:

&base::componentName == &derived::componentName

they refer to the same object, and initializing an object twice in a
"who laughs last, laughs the best" manner cannot be a good thing.

Cheers.

Vintz

'overridding' and 'inheritance' are terms that make sense only with objects. Class variables do not participate in object inheritance.

$9.4.2/2 - "In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator."

And...

It seems that static initializations cannot be overriden on the derived classes?

Please remember that overriding is only for virtual functions.

$10.3/2 - 'If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides97) Base::vf.

You may try to retrun the component name like so while gaining advantage of working with polymorphic code.

struct base{
   virtual char const* myname(){
      return "base";
   }
   virtual ~base(){}
};

struct derived : base{
   virtual char const* myname(){
      return "derived";
   }
};

int main(){}

if you try to initialize the static variable in the derived class before declaring in your derived class you will get redefinition error because derived class is-like base class and static variables are only defined once for class so second initialization causes redefinition error.

One of the correct way to do what you are intending is below;

struct a {
    virtual const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string a::ClassName = "StructA";

struct c : public a {
    const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string c::ClassName = "StructC";

a* a1 = new c();
cout << a1->getClassType() << endl;

NOTE In the above code, getClassType is virtual function and returns class type in string format. This function uses static variable and must be overridden in the derived class too. If you forget to override it, compiler will call base class version of the function and it will use the base class static variable instead of derived class static variable. So, it will returns the object type of base class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top