1

So I have the following c++ class

class MyClass:

public: 

    static void InitObject();

private:

    static MyObject *myObject;       

};

And then in the .cpp file I do

void MyClass::InitObject
{
    myObject = new MyObject();
}

However, I get a compiler error saying that "myObject" was referenced from InitObject() and then it says Linker command failed with exit code 1.

Why doesn't this work? How do I fix it?

user1855952
  • 1,515
  • 5
  • 26
  • 55

3 Answers3

6

Since static data members of classes in C++ need memory space that is separate from the instance memory, they need to be defined, in addition to being declared in the class.

You do that in a separate translation unit (in your CPP file) like this:

MyObject *MyClass::myObject;

This definition tells the compiler to allocate space for myObject in the static memory area. Without this definition, the code is going to compile, but the linker will report an error, because it is responsible for ensuring that all referenced static objects have memory allocated to them.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Extend your .cpp file with the following definition for myObject:

MyObject* MyObject::myObject = NULL;

NOTE:
For your particular case you might be better off saying:

class MyClass:
{
public: 
    static MyClass& instance();

private:
    MyClass() {}
};

and in .cpp file:

MyClass& MyClass::instance()
{
    static MyClass myInstance;
    return myInstance;
}

I'd prefer this over using new MyClass(). Any access to the instance() method will guarantee your instance is initialized exactly once, and you'll get a valid reference to it.
'Space' is completely allocated on the stack then, as well for the reference as for the instance itself.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
1

You never allocated space for MyObject::myObject. Put this in the CPP file:

MyObject* MyObject::myObject;
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Why do I need to allocate space for myobject? doesn't that happen when I do myObject = new MyObject()? – user1855952 Nov 23 '13 at 02:50
  • And do you mean MyObject *MyClass::myObject? – user1855952 Nov 23 '13 at 02:51
  • No. That allocates space for an object, `myObject` is a pointer, not an object. You never allocated space for `MyObject::myObject`, the pointer that you said in the header file was going to exist. (This is to your first question. I'm not sure what you mean in your second question. Are you asking about the style issue of where the space goes?) – David Schwartz Nov 23 '13 at 02:51