类成员的const, static修饰

本文详细解释了C++中static静态数据成员、static静态函数成员、const常数据成员、const常函数成员的概念及用法,包括初始化方法、访问规则和注意事项。

static和const修饰的类成员

 

类的static静态数据成员:

class A
{
   public:
      static int i ;
};

初始化方法: int  A::k=100;     

 //静态成员变量的初值只应该设定一次,不要把初始化操作放在类的构造函数中,因为构造函数可能一再被调用,也不要放在类的头文件中,因为头文件可能被载入许多地方从而被执行许多次。初始化时必须写上数据类型(int)和类名限定(A::),就像类的函数成员实现时必须写上函数返回值类型和类名限定一样。

 

类的static静态函数成员:

class A
{
   public:
      static void  fun( ) ;
};

实现方法: 

void A::fun( )
  {cout<<"class A fun()!";}

//在类的源文件.cpp里进行函数实现,实现方法跟普通函数成员的实现一样。类的静态函数只能访问该类的静态数据成员或静态函数成员。如果要访问非静态数据成员必须通过参数传递得到类对象名,然后通过对象名来访问。如下:

class A
{
public:
    static void  fun(A a ) ;
    int i;
}
;

函数实现:

void A::fun(A a )
{  
 a.i=55; 
 cout<<a.i;
}

 

类的const常数据成员:

class A
{
public:
    A(int j);
    const int i;
}
;

初始化方法:

A::A(int j):i(j)
{  }

//常数据成员只能通过构造函数初始化列表来获取初值。常数据成员得到初值后不能更新。

 

类的const常函数成员:

class A
{
public:
    A(int j,int m);
    const int i;
    int q;
    static int k;
    void  fun( )  const
}
;

 

函数实现:

A::A(int j,int m ):i(j),q(m)
{  }

int A::k=456;

void A::fun( ) const
{   k=789;     //正确,能对静态数据成员更新。
    q=111;     //错误,不能对普通数据成员更新。
     i=222;     //错误,常数据成员初始化后不能更新。
   cout<<i<<endl<<q<<endl<<k;   //正确,能访问所有数据成员。
}

//常函数成员能访问常数据成员,静态数据成员和普通数据成员,但不能对常数据成员和普通数据成员更新。

 

类的const对象(常对象)

const A(123,456);

类的常对象只能调用该类的常函数成员,由于常函数成员不能对常数据成员和普通数据成员更新,只能对静态数据成员更新,所以常对象不能修改自己的数据成员,也因此才能叫常对象。(静态成员不属于一个对象而属于整个类。)

 

类的静态常数据成员

class A
{
public:
    A(int j,int m);
   const int i;
   int q;
   static const int k;
   void  fun( )  const ; 
}
;

函数实现:

A::A(int j,int m):i(j),q(m)
{  }

const int A::k=789;     //类的静态常数据成员类似于静态数据成员赋初值,但要记得前面加const。

void A::fun( ) const
{   k=111;                  //错误,静态常数据成员也是常数据成员,常数据成员得到初值后不能更新。
    cout<<i<<endl<<q<<endl<<k;    //正确,能访问静态常数据成员。

 

<think>嗯,用户想理解C++const static修饰变量的作用和用法。这个问题涉及C++的核心概念,需要从多个维度解释清楚。 用户可能正在学习C++的存储类修饰符,或者遇到了相关代码需要解读。从问题表述看,用户应该有一定C++基础,但可能对staticconst的组合使用感到困惑。需要特别注意用户引用的三篇资料,其中提到关键矛盾点:static作用于类静态成员,const作用于实例状态保护,两者看似矛盾实则互补。 先拆解核心概念:const保证不可修改性,static表示静态存储期。当它们修饰类成员变量时: - static使变量脱离具体实例,属于整个类 - const保证该静态成员初始化后不可修改 这正是用户引用的[^1]提到的矛盾点解决方案:const static只适用于整型常量初始化 作用域方面要强调:const static成员具有类作用域(如引用[^2]示例),但生命周期是整个程序运行期(引用[^3]的内存区域划分)。需要澄清"作用域"和"生命周期"的区别: - 作用域决定哪里能访问变量 - 生命周期决定变量何时存在 使用场景要具体说明: 1. 类内定义数学常量(如π值) 2. 状态码映射(避免魔数) 3. 模板元编程中的固定值 特别要注意C++11前后差异:旧标准必须类外定义(odr-used),新标准允许类内初始化非整型。但用户可能用旧编译器,所以还是给出兼容写法比较稳妥。 最后生成的问题要覆盖: - 为什么整型才能类内初始化(历史设计原因) - 与constexpr的对比(现代C++替代方案) - 单例模式中的应用(实际工程案例)</think>在C++中,`const static`组合用于声明**类级别的常量**,其核心特性是:**生命周期为整个程序运行期,作用域限定在类内,且值不可修改**。以下是详细解析: --- ### **一、核心作用** 1. **常量性**(`const`) - 变量初始化后不可修改 - 必须在声明时初始化(C++11起支持类内初始化) 2. **静态性**(`static`) - 变量属于类本身,而非类的实例 - 所有实例共享同一内存地址 - 生命周期与程序相同 --- ### **二、作用域与访问规则** | 特性 | 说明 | |---------------|----------------------------------------------------------------------| | **作用域** | 类作用域(通过`类名::变量名`访问,如`MyClass::MAX_SIZE`)[^2][^3] | | **访问权限** | 受类访问控制符约束(`public`/`protected`/`private`) | | **内存位置** | 全局数据区(非栈或堆)[^3] | --- ### **三、使用方法** #### **1. 类内声明并初始化(C++11起)** ```cpp class MyClass { public: const static int MAX_SIZE = 100; // ✅ 整型常量可类内初始化 const static std::string NAME; // ❌ 非整型需类外定义 }; // 类外定义(必须!) const std::string MyClass::NAME = "Test"; ``` #### **2. 旧标准兼容写法(C++11前)** ```cpp class MyClass { public: static const int MAX_SIZE; // 仅声明 }; // 类外初始化 const int MyClass::MAX_SIZE = 100; ``` #### **3. 使用场景** ```cpp // 作为类常量使用 void MyClass::printLimit() { std::cout << "上限: " << MAX_SIZE; // 直接访问 } // 外部调用 std::cout << MyClass::MAX_SIZE; // 通过类名访问 ``` --- ### **四、关键注意事项** 1. **整型特例** - 只有**整型(`int`, `char`, `bool`等)** 支持类内初始化 - 非整型(如`string`, `double`)必须类外定义(避免链接错误) 2. **ODR-use规则** - 若变量仅用于编译期计算(如数组大小),可不提供类外定义 ```cpp int arr[MyClass::MAX_SIZE]; // ✅ 无需类外定义 ``` 3. **与`constexpr`对比** - C++11后优先用`constexpr static`替代(明确编译期常量): ```cpp constexpr static int MAX_SIZE = 100; // 强制编译期求值 ``` --- ### **五、典型错误示例** ```cpp class ErrorExample { public: const static float PI = 3.14; // ❌ 非整型类内初始化(Clang/GCC报错) }; // 正确写法 const float ErrorExample::PI = 3.14; // 类外定义 ``` > **本质原因**:`static`成员实际存在于类外,`const`仅保证类内不可修改。类内初始化整型是语法糖,非整型仍需类外分配存储[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值