c++ 中 static修饰的成员变量和成员函数

本文介绍了C++中static修饰类成员的相关知识。static类数据成员独立于类对象,被所有对象共享,需在类外初始化,可节省对象内存空间。static类成员函数属于类,无this指针,只能访问static修饰的类成员。

0.static修饰类中成员,表示类的共享数据

1.static类成员

在C++primer里面说过,static类成员不像普通的类数据成员,static类数据成员独立于一切类对象处在。static类数据成员是与类关联的,但不与该类定义的对象有任何关系。这句话什么意思?就是static不会想普通类数据成员一样每一个类对象都有一份,全部类对象是共享一个static类成员的,例如A类对象修改了static成员为1,那么B对象对应的static类对象成员的值也会是1.

注意:static类对象必须要在类外进行初始化

如:

static类对象必须要在类外进行初始化


 
  1. class Text

  2. {

  3. public:

  4. static int count;

  5. };

  6.  
  7. int Text::count=0;//用static成员变量必须要初始化

  8.  
  9. int main()

  10. {

  11. Text t1;

  12. cout<<t1.count<<endl;

  13. return 0;

  14. }//程序输出0

 

 

所有对象共享一个static类成员

static修饰的变量先于对象存在,所以static修饰的变量要在类外初始化。因为static是所有对象共享的东西嘛,必须要比对象先存在的。

 


 
  1. class Text

  2. {

  3. public:

  4. static int count;

  5. };

  6.  
  7. int Text::count=0;//用static成员变量必须要初始化

  8.  
  9. int main()

  10. {

  11. Text t1;

  12. Text t2;

  13.  
  14. t1.count = 100; //t1对象把static成员count改为100

  15. cout<<t2.count<<endl; //当t2对象打印static成员的时候,显示的是100而不是0

  16. return 0;

  17. }

好处:

用static修饰的成员变量在对象中是不占内存的,因为他不是跟对象一起在堆或者栈中生成,用static修饰的变量在静态存储区生成的,所以用static修饰一方面的好处是可以节省对象的内存空间。就如同你创建100个Person对象,而这100个对象都有共有的一个变量,例如叫国籍变量,就是Person对象的国籍都是相同的,那如果国籍变量用static修饰的话,即使有100个Person对象,也不会创建100个国籍变量,只需要有一个static修饰的国籍变量就可以了,这100个对象要用时,就会去调用static修饰的国籍变量。否则有100个Person变量,就会创建100个国籍变量,在国籍变量都是相同的情况下,就等于浪费空间了,因为你不需要创建100个国籍变量,

 

 

2.static类成员函数

由于static修饰的类成员属于类,不属于对象,因此static类成员函数是没有this指针的,this指针是指向本对象的指针。正因为没有this指针,所以static类成员函数

不能访问非static的类成员,只能访问 static修饰的类成员。

 


 
  1. class Text

  2. {

  3. public:

  4. static int fun()

  5. {

  6. return num;

  7. }

  8. static int count;

  9. int num;

  10. };

  11. int Text::count=5;//用static成员变量必须要初始化

  12.  
  13. int main()

  14. {

  15. Text t1;

  16. Text t2;

  17. t1.num=100;

  18.  
  19. t1.fun();//发生错误,fun函数return的是非static类成员 如果return count就正确

  20. return 0;

  21. }

### C++ 中 `static` 修饰成员变量的作用及用法 #### 1. **静态成员变量的定义** 在 C++ 中,当一个类的成员变量被声明为 `static` 时,该变量成为类的一个全局共享数据成员。这意味着无论创建多少个类的对象,这个静态成员变量只会在内存中存在一份副本,并由所有的对象共同拥有修改[^1]。 ```cpp class MyClass { public: static int count; // 声明静态成员变量 }; int MyClass::count = 0; // 类外初始化静态成员变量 ``` #### 2. **静态成员变量的特点** - **单一实例** 静态成员变量在整个程序运行期间只有一个拷贝,即使有多个对象实例化,它们也共享同一个静态成员变量[^2]。 - **存储位置** 静态成员变量通常存储于静态存储区域,而不是堆栈或动态分配的内存中[^3]。 - **生命周期** 静态成员变量的生命周期贯穿整个程序执行过程,在程序结束时才会释放其占用的空间[^4]。 - **访问方式** 可以通过类名直接访问静态成员变量(即无需创建对象),也可以通过对象来访问它。不过推荐使用类名的方式访问,因为这更清晰地表明它是属于类而非具体某个对象的一部分[^5]。 ```cpp MyClass::count = 10; // 使用类名访问 MyClass obj; obj.count = 20; // 使用对象访问 std::cout << MyClass::count << std::endl; // 输出:20 ``` #### 3. **初始化要求** 静态成员变量必须在类外部进行显式的初始化,而且初始化时不需要再次写入 `static` 关键字。如果尝试在类内部初始化非整型或者浮点类型的静态成员,则会引发编译错误[^5]。 ```cpp // 正确做法 class Example { public: static double pi; }; double Example::pi = 3.14159; // 错误示范 (无法在类内完成复杂类型初始值设定) class ErrorExample { public: static const char* message = "Hello"; // 编译器可能报错 }; ``` 对于常量静态成员变量 (`const`) ,允许直接在类体内赋初值,前提是它的类型支持这样的操作,比如基本数据类型或枚举类型[^5]。 ```cpp class ConstStaticDemo { public: static const int MAX_SIZE = 100; // 合法 }; ``` #### 4. **适用场景** 利用静态成员变量可以实现某些特定功能需求: - 统计已创建对象的数量。 - 实现资源池管理机制,让所有实例共用一组有限资源。 - 定义一些与业务逻辑紧密关联但又不依赖单个实体状态的数据项。 --- ### 示例代码展示 下面是一个完整的例子展示了如何运用 `static` 成员变量统计对象数目: ```cpp #include <iostream> using namespace std; class Counter { public: Counter() { objectCount++; } ~Counter() { objectCount--; } static int getObjectCount() { return objectCount; } private: static int objectCount; // 静态成员变量声明 }; int Counter::objectCount = 0; // 静态成员变量定义 int main() { cout << "Initial objects: " << Counter::getObjectCount() << endl; Counter c1, c2, c3; cout << "After creating three objects: " << Counter::getObjectCount() << endl; return 0; } ``` 此例中每当新建一个 `Counter` 的实例就会增加 `objectCount` 的数值;而销毁某实例则减少之。最终我们可以通过调用 `Counter::getObjectCount()` 方法查询当前存活了多少个此类别的对象。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值