MAG
MAG

Reputation: 3075

singleton with pointers require me to declare instance as public static

I am trying to learn singleton pattern and I am faced with a design dilemma .

A working singleton looks like following: note that static myClass * mc; is made public , just like public static myClass * getInstance

1) working_code

#include "iostream"
using namespace std;

class myClass {
private:  
   myClass() {          
   }
 void   operator = (const myClass &);
 myClass (const myClass & );

public:
   static myClass * mc;
   static myClass * getInstance () {
       cout << "\n getInstance  callsed \n";
       if (mc == NULL) {
           mc = new myClass();
       }
       return mc;
    }

 void print() {
     cout <<"\n call to print donem \n";
 }

};
myClass * myClass::mc =NULL;

int main() {    
    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

2) NOT_WORKING_CODE

Not working instance which gives compiler error. Please note that I tried to keep static myClass * mc; as private

#include "iostream"
using namespace std;

class myClass {
private: 
   static myClass * mc;
   myClass() {        
   }
 void   operator = (const myClass &);
 myClass (const myClass & );

public:
    static myClass * getInstance () {
        cout << "\n getInstance  callsed \n";
        if (mc == NULL) {
            mc = new myClass();
        }
        return mc;
    }

 void print() {
    cout <<"\n call to print donem \n";
 }

};

int main() {

    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

output: In function main': undefined reference tomyClass::mc' undefined reference to `myClass::mc'

problem :

1) Why am I getting the error for above NOT_WORKING_CODE

2) I think using public myClass::mc is against design rule as we should be making only the interface as public . Here problem I am facing is that the users of working code 1) above may directly access myClass::mc to call some function like print myClass::mc->print(); without first calling instance ..

ie when I changed the following in 1) above

int main() {
    myClass::mc->print();
    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

I got horrified as it printed

call to print donem 

 getInstance  callsed 

 call to print donem 

ie, I was able to call without a valid instance as that instance was created in getInstance . This means I could have well got some exception if print was accesing some pointers etc .

This hence shows that 1) is having a design flaw . How to correct the same is the question ...

Upvotes: 1

Views: 1041

Answers (2)

Arne Mertz
Arne Mertz

Reputation: 24626

//myClass * myClass::mc =NULL; The error appears because you commented that line out, not because you made the variable private. So to make the code work with the variable private, just don't comment that line out and it will compile.

See here:What is an undefined reference/unresolved external symbol error and how do I fix it?

But you should never use the singleton pattern this way. In fact, try to avoid using singletons at all, and if you really have to use them, use the Meyers Singleton (google for it!)

Upvotes: 2

Sanish
Sanish

Reputation: 1729

mc is a static data member, so it has to explicitly initialized as you did in your first case.

myClass * myClass::mc =NULL;

You missed to do this in the second case.

See this link http://www.parashift.com/c++-faq/link-errs-static-data-mems.html

BTW, that is a linker error not a compiler error.

Upvotes: 1

Related Questions