static、const和static const

本文详细介绍了C++中const常量成员、静态成员、静态常量成员的定义、初始化及使用方法,并通过实例说明了这些成员的特点与区别。

class Test
{
public:
    Test(): a(0){}  
       enum {size1=100, size2 = 200 };
private:
    const int a;  // 只能在构造函数初始化列表中初始化,这个似乎很少用到???
    static int b;
    const static int c; // 与static const int c;相同,可以在这里定义(如果以后在类中需要使用该变量的话).
}
int Test::b = 0;  // 不能以成员列表初始化,不能在定义处促使化,因为不属于某个对象。
const int Test:: c = 0;//注意:给静态成员变量赋值时,不在需要加static修饰。但const要加。

const定义的常量在函数执行之后其空间会被释放,而static定义的静态常量在函数执行后不会被释放其空间。

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

 

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

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

 

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。

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

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 定义之处进行初始化(笔者加:旧的编译器不允许static成员在其声明式上获得初值,新的可以。除此之外,还要注意在声明时初始化没有分配空间,如下:

class Test{

           public:

                 static const int MASK1 =  0xFFFF; //这是声明式,没有分配空间。

                 ...

           };

。其他情况在类里外都行。

比如:

class Test{

           public:

                 static const int MASK1;

                 const static int MASK2;

           };

const int Test ::MASK1 = 0xFFFF;

const int Test ::MASK2 = 0xFFFF;

它们没有区别,虽然  

一个是静态常量,  

一个是常量静态,  

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

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

 

下面是一个完整的例子:
#ifndef A_H_
#define A_H_
#include<iostream>
using namespace std;

 

   class A{
private:
    static int aa; //静态数据成员声明
    static const int count; //静态常数据成员声明(可以在此初始化)
    const int bb; //常数据成员
public:
    A(int a);
    static void print(); //静态成员函数
};

 



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 定义之处进行初始化(笔者加:旧的编译器不允许static成员在其声明式上获得初值,新的可以。除此之外,还要注意在声明时初始化没有分配空间,如下:

class Test{

           public:

                 static const int MASK1 =  0xFFFF; //这是声明式,没有分配空间。

                 ...

           };

。其他情况在类里外都行。

比如:

class Test{

           public:

                 static const int MASK1;

                 const static int MASK2;

           };

const int Test ::MASK1 = 0xFFFF;

const int Test ::MASK2 = 0xFFFF;

它们没有区别,虽然  

一个是静态常量,  

一个是常量静态,  

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

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

 

下面是一个完整的例子:
#ifndef A_H_
#define A_H_
#include<iostream>
using namespace std;

 

   class A{
private:
    static int aa; //静态数据成员声明
    static const int count; //静态常数据成员声明(可以在此初始化)
    const int bb; //常数据成员
public:
    A(int a);
    static void print(); //静态成员函数
};

 

<think>嗯,用户问的是“static constconst static的区别”。首先,我需要确定这两个关键字在C/C++中的作用以及它们的顺序是否会影响含义。 首先,static关键字在C/C++中有不同的用途。在全局变量或函数中,static限制了它们的链接性,使得它们只能在当前编译单元内访问。而在类的成员变量中,static表示该变量属于类而不是类的实例,所有对象共享同一个静态成员。 然后是const关键字,它用来声明常量,表明该变量的值不能被修改。在C++中,const变量默认具有内部链接,也就是它们的作用域被限制在当前编译单元。 现在的问题是这两个关键字的顺序是否影响。比如,在C++中,static constconst static是否等价?我记得在C++中,修饰符的顺序通常不影响,但可能在某些上下文中会有不同的效果。例如,在类的成员变量中,static const int是合法的,而const static int可能看起来不太常见,但可能也是正确的。 需要回忆C++的标准。根据C++标准,声明符的顺序通常不影响,除了在某些特定的情况下,比如volatileconst的组合。对于staticconst,它们的顺序不影响,所以static constconst static是等价的。不过,这可能在不同的编译器中有没有差异?需要确认。 另外,在C语言中,staticconst的顺序是否有区别?在C中,const变量默认外部链接,所以如果声明为static const,那么变量的作用域被限制到当前文件。而const static应该也是同样的效果,所以顺序不影响。 可能用户是在编写代码时遇到了这两种写法,或者在阅读别人的代码时产生了疑问。需要进一步考虑用户可能的背景。比如,用户可能是在C或C++中遇到这个问题,但问题中没有明确说明。这时候需要分别解释两种语言的情况。 另外,用户可能想知道是否有最佳实践或常见的写法推荐。例如,通常C++程序员更倾向于使用static const的顺序,而const static虽然正确,但可能不常见。 还需要检查是否有例外情况。例如,在类内部的静态常量成员,是否必须使用static const,或者是否允许const static。例如: class MyClass { static const int a = 10; // 合法 const static int b = 20; // 是否也合法? }; 在C++中,这两种都是合法的,所以顺序不影响。 总结:在CC++中,staticconst的顺序不影响,两者等价。但通常习惯写法是static const,可能更常见。 然后需要给出示例,说明两者的等价性,并指出常见的用法。同时提醒用户注意不同语言中的情况,比如CC++中的处理是否一致。 可能的相关问题包括:这两种写法的使用场景、是否影响变量的链接性、在类中的不同用法、历史原因导致的写法差异等。</think>在C/C++中,`static const``const static`的**语义完全相同**,仅书写顺序不同。编译器会将两者视为等价的组合,均表示“静态常量”。以下是具体分析: --- ### 核心结论 - **顺序无关性**:C/C++标准规定,类型修饰符(如`static`、`const`、`volatile`)的顺序不影响最终含义。因此: ```cpp static const int A = 10; // 合法 const static int B = 20; // 合法且等效 ``` - **常见写法**:`static const`更符合主流代码风格,因其强调“静态属性优先”(如类成员变量的声明习惯)。 --- ### 典型应用场景 1. **文件作用域的常量**(C/C++): ```cpp // 限制变量仅在当前文件可见(内部链接) static const float PI = 3.14159f; ``` 2. **类的静态常量成员**(C++): ```cpp class MyClass { public: static const int MAX_SIZE = 100; // 推荐写法 // const static int MAX_SIZE = 100; // 同样合法 }; ``` --- ### 注意事项 - **C与C++的差异**: - 在C语言中,`static const`变量默认具有内部链接,而C++中`const`变量默认已是内部链接(即使不加`static`)。 - **历史遗留代码**:某些旧代码可能因个人习惯或编译器兼容性使用`const static`,但现代标准无影响。 --- ### 示例对比 ```cpp // 写法1:static const static const int Threshold = 50; // 写法2:const static(完全等效) const static int Threshold = 50; ``` 两者均保证: - 变量生命周期为程序运行期; - 值不可修改; - 作用域被限制在声明所在的文件或类中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值