1

I'm getting an unresolved external symbol error in my C++ program. I have provided an MCVE below.

The constructor for the Foo class requires a single int parameter. I want Foo to be a singleton object.

In the Foo class, I have created two accessor functions for retrieving a pointer to the singleton object. The first passes an int parameter to allow construction of the object. The second does not require the parameter, in order to allow the object to be accessed by code that has no knowledge of the parameter.

The error occurs at link time when attempting to create an instance of Foo within main().

Is there a better way to do this, most importantly in order to avoid the error, and (less importantly) so the Foo interface doesn't impose the unfortunate requirement that the second accessor may not be called before the first?

#include <assert.h>

class Foo {
public:
    // Accessor function initializes m_param, and
    // returns pointer to singleton.
    static Foo* GetInstance (int *param)
    {
        // Foo singleton object is instantiated on first call
        // to this function
        static Foo instance (param);
        pInstance = &instance;
        return pInstance;
    }

    // Overloaded version of GetInstance() that may be called
    // after first calling static Foo* GetInstance(int *param).
    static Foo* GetInstance ()
    {
        // This alerts us if the other GetInstance() was not called first.
        assert (pInstance);

        return pInstance;
    }

private:
    // constructor
    Foo (int *param)
        : m_param (*param)
    {}

    // private var
    int m_param;

    // pointer to singleton object
    static Foo* pInstance;
};

// initialize static var
Foo* pInstance = static_cast<Foo*>(nullptr);


int main(int argc, char* argv[])
{
    int pInt;
    Foo* pFoo = Foo::GetInstance (&pInt);
    return 0;
}
sifferman
  • 2,955
  • 2
  • 27
  • 37

1 Answers1

1

To fix the link error, change

Foo* pInstance = static_cast<Foo*>(nullptr);

to

Foo* Foo::pInstance = static_cast<Foo*>(nullptr);

or better yet:

Foo* Foo::pInstance = nullptr;

Check this link out for an in-depth explanation

See this for an in-depth discussion on the best way to go about using the Singleton Pattern:

Community
  • 1
  • 1
wizurd
  • 3,541
  • 3
  • 33
  • 50
  • Thanks! It was a simple case of omitting the darn Foo:: prefix on the initializer. Your "better yet" suggestion works fine on C++11, but on my C++03 compiler it's necessary to change `nullptr` to `0` (but not `NULL`). – sifferman Dec 05 '15 at 05:30