2

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)

znat
  • 13,144
  • 17
  • 71
  • 106

2 Answers2

6

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;
}
bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • I understand it works(why too), but is this a good programming practice. Few thoughts on that would be appreciated. What I want to know is that is it encouraged as a programming practice to be used frequently. As far as I see, it makes the code confusing. – Aman Deep Gautam Jul 09 '13 at 01:38
  • I personally dislike the use of "name hiding" and avoid it whenever possible (I prefer distinct names for different variables to avoid mistakes). However, in this context it seems like there wouldn't be any mistakes, because you probably wouldn't ever want to access `Shape::name` from class `Rectangle`. It's a feature of the language and you're free to use it.. [see here](http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the). – bobobobo Jul 09 '13 at 01:41
  • Never thought it as a feature. Looks like a big answer, would surely read it later. Thanks..:) – Aman Deep Gautam Jul 09 '13 at 01:55
4

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

sedavidw
  • 11,116
  • 13
  • 61
  • 95