2011-07-21 143 views
3

我有一个一类是单定义如下C++单例类返回const引用

class myData { 
private: 
    myData (void); // singleton class. 
    // Copy and assignment is prohibted. 
    myData (const myData &); 
    myData & operator=(const myData &); 
    static myData* s_pInstance; 

public: 
    ~myData (void); 
    static const myData & Instance(); 
     static void Terminate(); 

    void myFunc() { cout << "my function..." ;} 
}; 

//在CPP文件。

myData* myData::s_pInstance(NULL); 

myData::myData(){} 

myData::~myData() 
{ 
    s_pInstance = NULL; 
} 

const myData& myData::Instance() 
{ 
    if (s_pInstance == NULL) 
    { 
     s_pInstance = new myData(); 
    } 

    return *(s_pInstance); // want to avoid pointer as user may deallocate it, so i used const referense 
} 

void main() { 

    (myData::Instance()).myFunc(); 

} 

我收到以下错误

错误C2662: 'myData的:: myFunc的':不能从 '常量myData的' 转换 '这个' 指针 'myData的&'

如何避免以上问题并从实例函数调用返回const引用的函数?

谢谢!

+0

请参阅:http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 –

回答

8

您希望将func()声明为常量成员函数,因此编译器知道它不会违反函数instance()的常量返回值。

您也可以使instance()函数返回一个“常规”参考,与const一样。

因此,要么转: void myFunc()void myFunc() const

或关闭: const myData& myData::Instance()myData& myData::Instance()

4

如果你调用一个const引用的函数,调用该函数也必须是const,你的情况void myFunc() const

否则,您可能会返回一个非const引用,如果更好的话。

3

错误说myData::Instance()是类的常量实例,它不能调用该myFunc(),因为myFunc()可能会改变的情况下,你不能改变一个const实例。

当然,你知道,myFunc()不能真正改变的情况下,但你必须做广告这个事实,具体如下:

void myFunc()const{ cout << "my function..." ;}

2

避免辛格尔顿是整个讨论如果你真的在实施一个单身人士,那么很有可能拥有所有邪恶的模式或源头,但是正如你所期望的那样,常量正确性不会在那里工作,所以你应该意识到一些陷阱。

首先你的错误:你Instance()静态成员返回一个const引用,这意味着你只能执行不修改对象的操作,即调用成员函数标记为const,或者如果存在的方式使用公共成员不会修改它们的值。我建议的解决方法是修改Instance()以返回非const引用,而不是像其他人所建议的那样创建const。


现在对常量正确性的问题进行更长时间的解释,以适用于您的特定Singleton问题。基本问题是,当你实现一个类型时,你将那些修改对象的成员与那些不成员的成员分开,并且将后者标记为const成员函数,以便编译器知道你的承诺(允许你调用该方法在一个常量对象上),并帮助你不要破坏它(如果你尝试修改方法定义中的状态,就会抱怨)。标记为const的方法既可以应用于常量对象,也可以应用于非常量对象,但未标记为const的方法只能应用于不是const的对象。

回到原始的代码段,如果实现一个单和的访问对象是由一个Instance()方法,它返回一个const参考的唯一方法,则基本上限制所有的用户代码仅使用const中实现的方法你的界面。这意味着有效地要么所有的方法都是非变异的,或者它们是无用的(不应该使用const_cast)。这又意味着如果您有任何非常量操作,您想要提供一个返回非const引用的Instance()方法。

您可以考虑实施Instance()的两个变体,但这不会真的有帮助。重载解析不会帮助用户代码确定要使用哪个版本,因此您最终将得到不同的方法:Instance(),ConstInstance()(选择您的姓名),这意味着它取决于用户代码来确定要使用哪一个。小的好处是,在他们的代码中,访问者的选择将有助于记录他们的预期用途,甚至可能会发现一些错误,但是更多的时候他们只会调用非常量版本,因为它的工作原理是

相关问题