2011-08-31 96 views
9

这个代码编译和运行没有出错时:为什么我可以从全局范围调用私有构造函数?

class foo{ 
    static foo *ref; 
    foo(){} 
    public: 
    static foo *getRef(){ 
     return ref; 
    } 
    void bar(){} 
}; 

foo* foo::ref = new foo; // the construcrtor is private! 

int main(int argc, const char *argv[]) 
{ 
    foo* f = foo::getRef(); 
    f->bar(); 
    return 0; 
} 

有人能解释为什么能构造被称为?

回答

15

该范围不是全局的 - 静态成员在类范围内,所以它们的初始化表达式也在类范围内。

+4

的确,用'foo * ref = new foo;'(注意不存在'foo ::')来替换表达式来获得编译器错误! –

10

答案是它在全局范围内不可用。一个静态成员的初始化器被定义为里面的类的作用域,所以它可以访问私有成员。

§9.4.2/ 2 [...]静态数据成员定义中的初始化表达式在其类(3.3.6)的范围内。

-2

这种形式的静态成员的初始化在旧的C++中不是必需的。它们在后来的C++版本中被强制执行。

而且,这种形式的静态成员初始化通常用于在创建任何类对象之前初始化静态成员。

(E.g) int MyClass::objectsCounter=0; 

但到了,

foo* foo::ref = new foo; 

这种说法你只是初始化通过创建一个新的对象的静态成员(这是指针类型)。

在这种情况下,您通过调用其自己的类的私有方法来初始化私有成员。

因此,这里没有全球范围的作用。

+0

-1你指的是C++的“旧版本”和“后期版本”*发布版本? AFAIK,自1998年第一个标准以来,这已经成为语言设计的一部分。而且,使用'new foo'总会创建一个对象。该语句执行两件事:a)创建一个类型为“foo”的实例;和b)为'foo :: ref'分配一个指向新分配对象的指针。 –

+0

@AndréCaron感谢您的意见。我编辑了我的帖子。我其实只是想说这个信息。但是我错误地传递了这些信息。关于老的和后来的C++: - ,现在提供的信息来自完整的参考-HERBERT。 –

+0

如果您计划使用专业C++编程,则应考虑使用[C++社区推荐的C++书籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 –

相关问题