不违反。类的静态成员,即使其生命周期长于主函数,但其仍能保证在任何情况(包括多线程环境)下,在使用对象前先调用构造函数构造对象、获取资源,在程序结束时调用析构函数析构对象、释放资源。所以这就是满足 RAII 了。补充“类的静态成员必须在类外初始化”这一语法是受继承自 C 的编译模型所限。在 C 的经典惯例中,头文件中只放声明(包括函数声明、extern 引导的外部变量声明等),不放实现(包括实现函数的函数体,以及变量的初始化等),而源文件中给出实现。每个源文件构成一个基本的编译单元,各个编译单元之间在编译时没有任何的信息共享。举个栗子,b.c 想用到 a.c 中的函数 void fun() / 全局变量,它可以在自己的文件开头写下声明语句 void fun(); / extern int x; 但是,更佳的实现方式是 a 模块提供一个头文件 a.h,在里面给出本模块所有对外暴露的函数/全局变量的声明,给 b.c 去 include。但是,如果 b.c 既不是自己写声明语句,也不 include 别的头文件里写的声明语句,而是在自己内部写出 void fun 的函数体,或者是 int x; 或者 int x = 0; 这种定义语句,那么,尽管 b.c 在被编译为 b.o 的过程中不会出编译错误,但是在 b.o 与 a.o 链接时,就会出现符号冲突。c++ 延习了这一经典模型,其虽然多了很多新语法,但仍分为声明语句和实现/初始化语句这两大类。class Foo
{
int a;
int f();
static int x;
};
首先,类的声明就属于声明语句,这上面,