znat
znat

Reputation: 13474

Inheritance - How to set a static variable depending of the class?

I have a hierarchy of classes with a static variable:

class Shape{
public:
    static string name;
}

class Rectangle: public Shape{

}

I would like to set name according to the class. So Shape::name should be "Shape" and Rectangle::name should be "Rectangle"

What I did is initialize the static variable in each of the .cpp implementation files. So in Shape.cpp:

string Shape::name = "Shape";

And in Rectangle.cpp:

string Shape::name = "Rectangle";

The linker does not like that and complains that there is a duplicate symbol. So how can I achieve that?

Note: I would like to stick with constructors with initialization lists (no implementation in the .cpp)

Upvotes: 2

Views: 203

Answers (2)

bobobobo
bobobobo

Reputation: 67224

What you're trying to do will never work. A static variable can only have one declaration where a value is assigned, not two separate ones in different files as you have tried. What you're trying to do is somewhat similar to trying to have two different function bodies stemming off the same function header. Won't work, and shouldn't work, duplicate symbol error.

To make it work you need another static variable called name in the Rectangle class. The derived class name variable hides the name variable in the Shape base class.

Then you would just use:

string Rectangle::name="Rectangle"

Try this out if not convinced

#include <stdio.h>
#include <string>
using namespace std ;
struct Base 
{
  static string name ;

  Base(){
    printf( "Base: A %s was created\n", name.c_str() ) ;
  }
} ;

string Base::name="Base";

struct Derived
{
  static string name ;

  Derived(){
    printf( "Derived: A %s was created\n", name.c_str() ) ;
  }
} ;

string Derived::name="Derived";



int main(int argc, const char * argv[])
{
  Base b ;
  Derived d;
}

Upvotes: 6

sedavidw
sedavidw

Reputation: 11691

You could try making a virtual function that returns the name. That might be cleaner. I also believe that if you make the name private you would be okay as well

Upvotes: 4

Related Questions