(转 )C++ static、const和static const 以及它们的初始化

const定义的常量在函数执行之后其空间会被释放,而static定义的静态常量在函数执行后不会被释放其空间。但不论是Const还是static  他们定义的内容都会随着程序的结束而被系统清楚。

static 表示的是静态的。类的静态成员函数,成员变量是和类相关的,不是和类的具体对象相关,即使没有具体的对象,也能调用类的静态成员函数,成员变量。一般的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。

在c++中,static静态成员变量不能在类内部初始化。

在c++中,const常量成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。

所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。

const数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。

如:

class Test
{
public:
 Test(): a(0){}
  enum {size1=100, size2 = 200 };

private:
    const int a;  // 只能在构造函数初始化列表中初始化,这个似乎很少用到???

    static int b;//这个变量与类 Test有关 而与之类的实例化对象没啥关系。。

    const static int c; // 与static const int c;相同,可以在这里定义(如果以后在类中需要使用该变量的话).

}

int Test::b = 0;  // 不能以成员列表初始化,不能在定义处促使化,因为不属于某个对象。

const int Test:: c = 0;//注意:给静态成员变量赋值时,不在需要加static修饰。但const要加。

const 成员函数,主要的目的是防止修改对象的内容。即:int Fun() const; 不可以修改对象的数据,可以访问对象的数据,访问成员函数时,只能是const的,不能是non_const的成员函数。

static成员函数,主要的目的是作为类作用域的全局函数。不能访问类的非静态数据成员。类的静态成员函数的没有this指针,这导致:

1.  不能直接存取类的非静态成员变量,调用非静态成员函数

2.  不能被声明为virtual

下面是关于static,const,static const , const static成员的初始化问题。

1.类里的const成员初始化:

在一个类里建立一个const时,不能给它初值。像

class foo

{

private:

const int i = 100;                // error !!!    必须要做类foo的构造函数里面初始化

public:

foo(){}

......

};

这样的初始化方式是不能通过编译的,因为在类对象里进行了存储空间分配,编译器不能知道const的内容是什么,所以不能把它用作编译期间的常量。这意味着对于类里的常数表达式来说,const就像它在C中一样没有作用。因此这个初始化工作必须发生在构造函数里,并且,要在构造函数的某个特别的地方。因为const必须在建立它的地方被初始化,所以在构造函数的主体里,const必须已初始化了,否则,就只有等待,直到在构造函数主体以后的某个地方给它初始化,这意味着过一会儿才给const初始化。当然,无法防止在在构造函数主体的不同地方改变const的值。

构造函数初始化表达式

class foo

{

private:

const int i = 100;

public:

foo(){......}

......

};

如果构造函数是在类外定义,则可以这样写:

class foo

{

private:

const int i;

public:

foo();

......

};

foo ::foo() : i (100) {......}        // 初始化列表

2.类里的static成员初始化:

类中的static变量是属于类的,不属于某个对象,它在整个程序的运行过程中只有一个副本,因此不能在定义对象时对变量初始化,就是不能用构造函数来初始化。其正确的初始化方式是:

<数据类型><类名> ::<静态数据成员名> = <值> ,例如

class foo

{

private:

static int i;

public:

foo();

......

};

int foo ::i = 100;

这表明:

(1)初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。

(2)初始化时不加该成员的访问权限控制符private,public等。

(3)初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。

3.类里的static const 和const static成员初始化:

在找static成员的初始化学习资料时,我发现了网上有很多关于 static const 成员,也就是全局的静态常量的初始化的资料。const成员要在构造函数初始化,而static成员在需要在在类体外初始化,那么static const和 const static 的成员应该在哪里进行初始化呢?这两个写法又会有什么不一样吗?其实他俩都一样。在借阅《Thinking in c++》中文版188页和做了相关实验后,我认为若在类内使用的话,static const 则必须在static const 定义之处进行初始化。其他情况在类里外都行。

比如:

class Test{

public:

static const int MASK1;

const static int MASK2;

};

const int Test ::MASK1 = 0xFFFF;

const int Test ::MASK2 = 0xFFFF;

它们没有区别,虽然

一个是静态常量,

一个是常量静态,

静态都将存储在全局变量区域,其实最后结果都是一样的。

可能在不同编译器内,不同处理,但是最后结果是一样的。

下面是一个完整的例子:

 1 #ifndef A_H_
 2 #define A_H_
 3 #include<iostream>
 4 using namespace std;
 5
 6
 7
 8 class A{
 9     private:
10         static int aa; //静态数据成员声明
11         static const int count; //静态常数据成员声明(可以在此初始化)
12         const int bb; //常数据成员
13     public:
14         A(int a);
15       static void print(); //静态成员函数
16 };
17
18
19
20    A::A(int a):bb(a) { //常成员的初始化
21    aa += 1;
22 }
23
24
25
26    void A::print() {
27    cout << "connt=" << count<< endl;
28    cout << "aa=" << aa << endl;
29 };
30
31
32
33    int A::aa = 0; //静态成员定义
34 const int A::count = 25; //静态常成员初始化
35 #endif
36
37
38
39    int main(){
40  A a(10);
41  A::print(); //通过类访问静态成员函数
42  a.print(); //通过对象访问静态成员
43 }

但是注意:将static const datamember的申明放在头文件中时,新的C++标准支持,但VC6.0却不支持

时间: 2024-10-18 17:34:02

(转 )C++ static、const和static const 以及它们的初始化的相关文章

C++中类const、static、static const成员变量

#include<iostream> using namespace std; class Test { private: const int a;  //const 成员变量只能在构造函数的成员初始化列表中初始化,不能在函数体中和其他地方 static int b; //static 成员变量需要在全局范围内初始化,格式: 类型名 类名::变量名 = 值 static const int c;//static const 成员变量需要在全局范围内初始化,格式:类型名 类名::变量名 = 值

const、static变量存放位置

我们将以下面的例子介绍const变量和static变量的存放位置: static int val_a = 1; // 初始化的静态变量 int val_b = 2;        // 全局变量 const int val_c = 3;  // const 全局变量 static int val_d;     // 未初始化的静态变量 int val_e;            // 未初始化的全局变量 int main() { static int val_f = 5;  // 初始化的局部静

C++ 中 const 和 static 的作用

目录 const 的主要应用如下: const 关键字使用的注意点: C++中static关键字有三个明显的作用: const的主要应用如下: const 用于定义常量:const定义的常量编译器可以对其进行数据静态类型的安全检查. const 修饰函数形式参数:当输入参数为用户自定义类型和抽象数据类型的时候,将"值传递"改为"const 引用传递" 可以提高效率. const 修饰函数的返回值:如果给"指针传递"的函数返回值加const,则返回

【转】const和static readonly

我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等.在多数情况下可以混用.二者本质的区别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值.而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值.明白了这个本质区别,我们就不难看出下面的语句中static readonly和const能否互换了: 1. static readonly MyClass myins = new M

C++ Primer 学习笔记_25_类与数据抽象(11)--const 用法小结、static与const以及static const(const static)

一.const 用法总结 1.可以对const 的用法做个小总结: const int n = 100;  //定义常量 const Test t(10); const int & ref = n;   //const引用 int& ref = n;  //Error [const与指针] const int* p; //const出现在*前面,表示*p是常量 (*p = 200; //Error) int * const p2;  //const出现在*后面,表示p2是常量 (p2 =

const和static的区别

static关键字: 1)函数体内static变量的作用范围为函数体.不同于auto变量.该变量的内存只被分配一次.因此其值在下次调用时仍维持上次的值. 2)在模块内的static全局变量可以被模块内的所有函数访问.但不能被模块外的其他函数访问. 3)在模块内的static函数只可被这一模块内的其它函数调用.这个函数的使用范围被限制在声明它的模块内. 4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制. 5)在类中的static成员函数属于整个类所有,这个函数不接受thi

《OOC》笔记(1)——C语言const、static和extern的用法

<OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用const修饰的函数形参 直接修饰 一个形如 int Minus(const int a, const int b, int testCase); 的函数,const的意义是什么呢? 答:参数a被const修饰,说明在Minus函数内,编译器不允许a被别的变量(例如x)赋值(修改).参数b同理. 如果你写了a

static, const 和 static const 变量的初始化问题

const 常量的在超出其作用域的时候会被释放,但是 static 静态变量在其作用域之外并没有释放,只是不能访问. static 修饰的是静态变量,静态函数.对于类来说,静态成员和静态函数是属于整个类的,而不是属于对象.可以通过类名来访问,但是其作用域限制于包含它的文件中. static 变量在类内部声明,但是必须在类的外部进行定义和初始化. const 常量在类内部声明,但是定义只能在构造函数的初始化列表进行. class A { public: A(int a) : constNum(a)

php中const和static的区别和联系

1.const是类中的常量,类外用define来定义常量2.const只可以修饰类的属性,不能修饰类的方法,static可以修饰属性,也可以修饰方法3.const和static都属于类本身,而不属于new后的类实例.类内访问使用self::,类外使用类名::来访问;类内的$this指代类实例本身,const和static属于类本身,所以无法用$this访问4.self::NAME指代const,self::$name指代static;const是常量,是不需要变量符号的.static修饰的变量,