带指针的单例需要我将实例声明为公共静态

时间:2013-05-27 06:39:16

标签: c++ pointers singleton

我正在努力学习单身人士模式,我面临着设计困境。

工作单身如下: 注意静态myClass * mc;公开,就像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

不工作的实例会产生编译错误。请注意,我尝试将static myClass * mc;保密为私有

#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;
}

输出:     在函数main': undefined reference to myClass :: mc'中     未定义的引用`myClass :: mc'

问题:

1)为什么我收到上述NOT_WORKING_CODE

的错误

2)我认为使用public myClass :: mc是违反设计规则的,因为我们应该只将接口设为public。我面临的问题是上面的工作代码1)的用户可以直接访问myClass :: mc来调用一些函数,比如print myClass :: mc-&gt; print();没有先调用实例..

即当我在上面的1)中更改了以下内容时

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

我打印时感到恐惧

call to print donem 

 getInstance  callsed 

 call to print donem 

即,我可以在没有有效实例的情况下调用,因为该实例是在getInstance中创建的。这意味着如果print正在访问某些指针等,我可能会遇到一些异常。

这因此表明1)具有设计缺陷。如何纠正同样的问题......

2 个答案:

答案 0 :(得分:2)

//myClass * myClass::mc =NULL; 出现错误是因为您注释掉了该行,而不是因为您将变量设为私有。因此,为了使代码与变量private一起工作,只是不要对该行进行注释,它将进行编译。

见这里:What is an undefined reference/unresolved external symbol error and how do I fix it?

但是你不应该这样使用单身模式。事实上,尽量避免使用单身,如果你真的必须使用它们,请使用Meyers Singleton(google for it!)

答案 1 :(得分:1)

mc是一个静态数据成员,因此必须像在第一种情况下那样明确初始化。

myClass * myClass::mc =NULL;

你错过了第二种情况。

请参阅此链接http://www.parashift.com/c++-faq/link-errs-static-data-mems.html

BTW,这是链接器错误而不是编译器错误。