当前位置: 首页 > news >正文

C++(18)—类和对象(下) ③static成员

文章目录

  • 一、静态成员的概念与特性
  • 二、静态成员变量的定义与使用
    • 1. 定义规则
    • 2. 使用场景
  • 三、静态成员函数的特性与限制
    • 1. 核心特点
    • 2. 使用示例
  • 四、静态成员与普通成员的对比
  • 五、静态成员的应用场景
  • 六、最佳实践与注意事项
  • 七、总结

一、静态成员的概念与特性

在C++中,static关键字用于修饰类的成员变量和成员函数,使其成为静态成员。静态成员与类的实例无关,而是属于类本身。其核心特性如下:
在这里插入图片描述

二、静态成员变量的定义与使用

1. 定义规则

声明:在类内用static关键字声明。

初始化:必须在类外单独初始化,且不带static关键字。
class A {
private:
    static int _count;  // 类内声明
};

int A::_count = 0;      // 类外初始化(必须!)

2. 使用场景

资源共享:例如全局计数器、共享缓存。

对象计数:统计程序中创建的对象数量。
#include <iostream>
using namespace std;

class A {
public:
    A() { ++_count; }          // 构造函数:计数+1
    A(const A&) { ++_count; }  // 拷贝构造:计数+1
    ~A() { --_count; }         // 析构函数:计数-1

    static int GetCount() { return _count; }

private:
    static int _count;  // 静态成员变量声明
};

int A::_count = 0;      // 类外初始化

int main() {
    A a1;               // 计数=1
    A a2 = a1;          // 计数=2
    {
        A a3;           // 计数=3
    }                   // 离开作用域,计数=2
    cout << A::GetCount();  // 输出:2
    return 0;
}

三、静态成员函数的特性与限制

1. 核心特点

无this指针:无法直接访问类的非静态成员。

访问权限:只能访问静态成员变量和函数。

调用方式:可通过类名或对象调用。

2. 使用示例

class Logger {
public:
    static void Log(const string& msg) {
        // 只能访问静态成员
        _logCount++;
        cout << "[" << _logCount << "] " << msg << endl;
    }

private:
    static int _logCount;  // 静态成员变量
};

int Logger::_logCount = 0;

int main() {
    Logger::Log("Start program");  // 输出:[1] Start program
    Logger logger;
    logger.Log("Initialized");     // 输出:[2] Initialized
    return 0;
}

四、静态成员与普通成员的对比

在这里插入图片描述

五、静态成员的应用场景

全局计数器:统计对象实例数量(如示例代码)。

资源共享:例如数据库连接池、线程池。

工具类函数:提供与类相关但不依赖对象状态的工具方法(如数学计算函数)。

单例模式:通过静态成员实现单例对象的唯一性。

六、最佳实践与注意事项

初始化位置:静态成员变量必须在类外初始化,否则会导致链接错误。

线程安全:多线程环境下,静态成员的访问需加锁保护。

避免滥用:过度使用静态成员可能导致代码耦合度高,难以维护。

C++17内联静态成员:C++17支持在类内直接初始化静态成员(需inline关键字):
class Example {
public:
    inline static int _count = 0;  // C++17特性
};

七、总结

静态成员是C++中实现类级别数据共享和功能封装的重要工具。理解其初始化规则、访问限制及适用场景,能够帮助开发者编写出更高效、健壮的代码。合理使用静态成员,可以简化设计模式(如单例模式)的实现,提升程序的可维护性。


文章转载自:

http://fmzImq3F.pnmdb.cn
http://74rF3kMM.pnmdb.cn
http://QcloSV6S.pnmdb.cn
http://8DWQnIt5.pnmdb.cn
http://Sp6GGnOl.pnmdb.cn
http://JgxuADBH.pnmdb.cn
http://JYtFi6sU.pnmdb.cn
http://LvQyTiJP.pnmdb.cn
http://a6RnaWXN.pnmdb.cn
http://w8e2QJMl.pnmdb.cn
http://x2ysBQzy.pnmdb.cn
http://W8obDFKQ.pnmdb.cn
http://hoc16tYf.pnmdb.cn
http://8hWioeMs.pnmdb.cn
http://XeT7bo5m.pnmdb.cn
http://qC8YSH0C.pnmdb.cn
http://xv0oCA4T.pnmdb.cn
http://bjo03ebQ.pnmdb.cn
http://fAkzGcWq.pnmdb.cn
http://lY7MZxXT.pnmdb.cn
http://2cBLOSo9.pnmdb.cn
http://b2GGjoGr.pnmdb.cn
http://zrppToZS.pnmdb.cn
http://cqTnGsfN.pnmdb.cn
http://xwYAMdAx.pnmdb.cn
http://pEEvRhzH.pnmdb.cn
http://aanStlO8.pnmdb.cn
http://qDRtDwSP.pnmdb.cn
http://SvLNBTuE.pnmdb.cn
http://2mSCKvin.pnmdb.cn
http://www.dtcms.com/a/116471.html

相关文章:

  • 再看自适应RAG方法:SEAKR|PIKE-RAG|DeepRAG
  • skynet.dispatch可用的已注册的协议类型
  • 前端开发中的单引号(‘ ‘)、双引号( )和反引号( `)使用
  • 【AIGC】零样本学习方法综述(TPAMI 2023 研究综述)
  • java面向对象练习
  • Linux进程控制(五)之做一个简易的shell
  • 玄机靶场:apache日志分析
  • 4.7-python request库的基本使用
  • 【区块链安全 | 第三十三篇】备忘单
  • 其它理论原则
  • 从存储仓库到智能中枢:AI时代NAS的进化革命
  • Android使用声网SDK实现音视频互动(RTC)功能
  • 【算法应用】基于融合A星-粒子群算法求解六边形栅格地图路径规划
  • 分行经理个人简历
  • scala课后总结(7)
  • 虚引用软引用强引用弱引用
  • 多模态大语言模型arxiv论文略读(四)
  • 【Django】教程-11-ajax弹窗实现增删改查
  • WSL2迁移教程:如何备份和转移Ubuntu子系统到新位置
  • [C++面试] C++中各类括号的差异:[]、{}、<>、()
  • Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结
  • 【HFP】蓝牙HFP服务层连接与互操作性核心技术研究
  • Siamrpn跟踪模型转RKNN模型
  • 工业级远程无线开关控制模块--轻松实现一对多MESH组网
  • #关于process.env.NODE_ENV 与 import.meta.env 相关了解
  • AE MDX II 电源 User Manual
  • C++11(右值引用和移动语义)
  • stm32week10
  • TensorFlow深度学习实战——字符嵌入、子词嵌入、句子嵌入和段落嵌入
  • 笔试专题(七)