2013-04-29 96 views
-2
class ClassObject { 
public: 
    ClassObject(); 
    virtual ~ClassObject(); 
private: 
    int x; 
}; 

int ClassObject::x=10; 

为什么它编译失败? 我认为如果静态成员可以用这种方式进行初始化,那么对于非静态成员也应该是可能的。为什么我不能在类声明之外初始化非静态成员?

+6

是什么让你觉得呢? – 0x499602D2 2013-04-29 23:57:57

+0

但是,如果它是非静态的,它需要设置在一个对象上,这里没有任何对象。 ...或者当你创建一个新的对象时,你的意思是初始化的默认值,即将这段代码移出构造函数吗? – Rup 2013-04-29 23:58:01

+0

如果我想'x'是10以外的东西呢? – yngccc 2013-04-29 23:58:04

回答

5

静态成员是特殊的。 只要类定义为,它们就会分配给它们的内存。无论这个类有多少个对象,我们创建了所有这些对象都指向同一块内存。

非静态成员情况并非如此。除非您创建该特定类的对象,否则非静态成员不会分配任何内存,因此尝试以上述方式实例化它们会导致编译器错误。

0

我猜你的意思是,宣布用于初始化x任何新ClassObject价值,即你的意思是等同于

ClassObject() : x(10) { } 

与语法的问题是,编译器需要生成代码在每个ClassObject构造函数中进行初始化;即只有在定义所有构造函数的编译单元中有可用的初始化以及任何隐式生成一个的编译单元时,它才能工作。唯一的办法是保证这个值是在类定义内部设置的,而不是像你所拥有的那样。 (但是现在可以在C++ 11中使用 - 请参阅tacp评论中的链接。)

如果我们确实想让您的语法工作,那么我们需要将声明的值作为隐藏静态一种方法,任何构造函数都会将其选中并知道将其用作x的初始值。然而,这个静态可能存在也可能不存在,我们可以知道,对于不同编译单元中的构造函数,唯一的一点是链接时间。因此,如果存在(或冗余数据),我们要么产生额外的冗余代码来从这个隐藏的静态初始化x,要么我们要求链接时间代码生成来解决这个问题,这给编译器开发人员带来了很大的负担。这是可能的,但是,如果这不被允许的话,它更简单。