tags:

views:

825

answers:

3

I'm getting an Undefined reference error message, on this statement:

GlobalClass *GlobalClass::s_instance = 0;

Any ideas? Code is shown below:

================================================

#ifndef GLOBALCLASS_H_
#define GLOBALCLASS_H_

#include <string>
class GlobalClass {

public:

    std::string get_value();

    void set_value(std::string);

    static GlobalClass *instance();

    static GlobalClass *s_instance;

private:

    std::string m_value;
};

#endif /* GLOBALCLASS_H_ */

===============================================

#include <string>
#include "GlobalClass.h"



/*
 GlobalClass(int v = 0)
 {
 m_value = v;
 }
 */

    static GlobalClass *s_instance;

    std::string GlobalClass::get_value()
    {
        return m_value;
    }

    void GlobalClass::set_value(std::string v)
    {
        m_value = v;
    }

    static GlobalClass *instance() {
        if (!s_instance)
         s_instance = new GlobalClass;
        return s_instance;
    }

===========================================================

#include <iostream>
#include "GlobalClass.h"

using namespace std;

int main() {

    GlobalClass::s_instance = 0;


    std::string myAddress = "abc";
    GlobalClass::instance()->set_value(myAddress);  \\ <=== compiler error
    std::cout << "====>address is is " << GlobalClass::instance()->get_value()
      << std::endl;
    return 0;
}
A: 

If I understand what you want to do is only a matter of using this:

GlobalClass::s_instance = 0;
Aragorn
Yes, thanks, that got me past that one. I've reposted with the next one...
Jack BeNimble
+2  A: 

Are you trying to implement a Singleton class? Ie. You want only a single instance of of the class, and you want that instance available to anyone who includes the class. I think its commonly known as a Singleton, the following example works as expected:

Singleton.h:

#include <string>
class Singleton
{
public:
    static Singleton* instance()
    {
     if ( p_theInstance == 0 )
      p_theInstance = new Singleton;
     return p_theInstance;
    }
    void setMember( const std::string& some_string )
    {
     some_member = some_string;
    }
    const std::string& get_member() const
    {
     return some_member;
    }

private:
    Singleton() {}
    static Singleton* p_theInstance;
    std::string some_member;
};

Singleton.cpp:

Singleton* Singleton::p_theInstance = 0;

main.cpp:

#include <string>
#include <iostream>
#include "Singleton.h"

int main()
{
    std::string some_string = "Singleton class";
    Singleton::instance()->setMember(some_string);
    std::cout << Singleton::instance()->get_member() << "\n";
}

Note that the constructor is private, we don't want anyone to be creating instances of our singleton, unless its via the 'instance()' operator.

DeusAduro
Why does the header file have the definitions of the methods within them?
Jack BeNimble
It doesn't have to, you can put them in the .cpp, that was me being lazy and not wanting to write them over there. However the above code is still valid, and I have compiled and tested it.
DeusAduro
I tried it, and if I add "include Singleton.h" into Singleton.cpp, it compiles and runs. I'm going to put it into the main project and see if it work. Thanks!
Jack BeNimble
Err ya that was missing from the .cpp sorry.
DeusAduro
No problem - at last I got something working. Phew! Thanks a lot!
Jack BeNimble
+1  A: 

When you declare a static field s_instance in your .h file, it only tells the compiler that this field exists somewhere. This allows your main function to reference it. However, it doesn't define the field anywhere, i.e., no memory is reserved for it, and no initial value is assigned to it. This is analogous to the difference between a function prototype (usually in a .h file) and function definition (in a .cpp file).

In order to actually define the field, you need to add the following line to your .cpp file at global scope (not inside any function):

GlobalClass* GlobalClass::s_instance = 0;

It is important that you don't add the static modifier to this definition (although you should still have the static modifier on the declaration inside the class in the .h file). When a definition outside a class is marked static, that definition can only be used inside the same .cpp file. The linker will act as if it doesn't exist if it's used in other .cpp files. This meaning of static is different from static inside a class and from static inside a function. I'm not sure why the language designers used the same keyword for three different things, but that's how it is.

Jay Conrod
Jay, I have done as you suggested, the explanation makes sense. Unfortuntely, I'm still getting the same linker error on the two remaining references go GlobalClass in main...
Jack BeNimble