LiSheng's blog LiSheng's blog
首页
笔记
个人简历
随笔集
GitHub (opens new window)
首页
笔记
个人简历
随笔集
GitHub (opens new window)
  • golang

  • cplus

    • 内存相关

    • 面向对象

      • 相关问题
      • 构造、析构顺序
      • 对象内存布局
      • 静态、动态多态
      • 虚函数表
      • 重载、重写、覆盖
      • 构造函数不能是虚函数
      • CRTP模式的原理和用途
      • 移动语义move
      • 构造函数初始化列表
      • 静态成员变量和函数
        • 多重继承
        • 菱形问题与虚继承
        • 对象池
      • STL相关

      • 内置数据结构
      • 数据结构示例
      • go和c++对比
      • 关键字

    • leetcode

    • 存储技术

    • 分布式系统

    • 计算机网络

    • Linux操作系统

    • Redis

    • 其他

    • 笔记
    • cplus
    • 面向对象
    lisheng
    2024-09-10
    目录

    静态成员变量和函数

    在C++中,静态成员变量和静态成员函数是类的成员,但它们与类的实例对象无关,而是属于类本身。它们在对象模型中的表现与非静态成员有所不同。下面详细解释它们的定义、初始化以及在对象模型中的体现。

    # 一、静态成员变量

    # 1. 定义

    静态成员变量是与类相关联的变量,而不是与类的某个具体对象相关联。它们在所有对象之间共享,因此只有一个实例存在。

    # 2. 初始化

    • 声明:在类定义中声明静态成员变量,使用 static 关键字。

      class MyClass {
      public:
          static int staticVar; // 声明静态成员变量
      };
      
      1
      2
      3
      4
    • 定义和初始化:静态成员变量需要在类定义外进行定义和初始化。即使你在类内声明了它,必须在类外进行实际的定义和初始化。

      int MyClass::staticVar = 0; // 定义并初始化静态成员变量
      
      1

      静态成员变量的初始化只会执行一次,不管创建多少个对象。

    # 3. 对象模型中的体现

    • 存储位置:静态成员变量不存储在类的对象实例中,而是存储在静态存储区。这意味着它们在所有类实例中共享相同的存储空间。

    • 访问:可以通过类名直接访问静态成员变量,也可以通过对象访问,但不推荐这种做法。

      MyClass::staticVar = 10; // 推荐的访问方式
      
      MyClass obj;
      obj.staticVar = 20; // 也可以访问,但不推荐
      
      1
      2
      3
      4

    # 二、静态成员函数

    # 1. 定义

    静态成员函数是与类相关联的函数,而不是与类的某个具体对象相关联。它不能访问非静态成员变量或非静态成员函数,因为它没有 this 指针。

    # 2. 初始化

    静态成员函数不需要初始化,因为它们不涉及任何数据成员的存储,只是一个普通的函数。声明和定义都在类的内部和外部完成:

    • 声明:

      class MyClass {
      public:
          static void staticFunction(); // 声明静态成员函数
      };
      
      1
      2
      3
      4
    • 定义:

      void MyClass::staticFunction() {
          // 实现静态成员函数
      }
      
      1
      2
      3

    # 3. 对象模型中的体现

    • 存储位置:静态成员函数也不存储在类的对象实例中,而是作为类的一部分存储在静态存储区。

    • 访问:可以通过类名直接调用静态成员函数,也可以通过对象调用,但不推荐这种做法。

      MyClass::staticFunction(); // 推荐的访问方式
      
      MyClass obj;
      obj.staticFunction(); // 也可以访问,但不推荐
      
      1
      2
      3
      4

    # 三、示例

    #include <iostream>
    
    class MyClass {
    public:
        // 静态成员变量
        static int staticVar;
        
        // 静态成员函数
        static void staticFunction() {
            std::cout << "Static function called" << std::endl;
        }
    };
    
    // 定义并初始化静态成员变量
    int MyClass::staticVar = 0;
    
    int main() {
        MyClass::staticVar = 10; // 通过类名访问静态成员变量
        std::cout << "StaticVar: " << MyClass::staticVar << std::endl;
    
        MyClass::staticFunction(); // 通过类名调用静态成员函数
    
        MyClass obj;
        obj.staticVar = 20; // 通过对象访问静态成员变量
        obj.staticFunction(); // 通过对象调用静态成员函数
    
        std::cout << "StaticVar: " << MyClass::staticVar << std::endl; // 验证共享数据
        return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    # 四、总结

    1. 静态成员变量和静态成员函数属于类本身,而不是类的实例。静态成员变量在所有实例之间共享,静态成员函数没有 this 指针,因此不能访问非静态成员。
    2. 静态成员变量必须在类外定义和初始化,而静态成员函数不需要初始化。
    3. 对象模型:静态成员变量和静态成员函数不占用对象实例的内存,它们在静态存储区中管理,类的所有对象共享同一份静态成员数据。
    编辑 (opens new window)
    上次更新: 2024/09/13, 11:59:12
    构造函数初始化列表
    多重继承

    ← 构造函数初始化列表 多重继承→

    最近更新
    01
    ceph分布式存储-对象存储(RGW)搭建
    10-27
    02
    ceph分布式存储-集群客户端连接
    10-27
    03
    ceph分布式存储-管理crushmap
    10-27
    更多文章>
    Theme by Vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式