news 2026/4/14 22:45:27

C++ 静态数据成员与静态成员函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 静态数据成员与静态成员函数

C++ 静态数据成员与静态成员函数

1. 概述

在 C++ 中,使用static关键字修饰的类数据成员或成员函数,称为静态数据成员静态成员函数。它们与类本身关联,而非与类的某个具体对象关联。静态成员在整个程序运行期间只有一份副本,被所有类对象共享。

2. 静态数据成员

2.1 定义与初始化

静态数据成员必须在类内声明,在类外(文件作用域)定义并初始化(除静态常量整型成员外)。定义时不需要重复static关键字,但需要加上类名和作用域运算符::

// CountedObject.h#ifndefCOUNTED_OBJECT_H#defineCOUNTED_OBJECT_HclassCountedObject{public:CountedObject();~CountedObject();staticintGetCount();// 静态成员函数声明private:staticintcount_;// 静态数据成员声明(引用性声明)};#endif
// CountedObject.cpp#include"CountedObject.h"// 静态数据成员定义性声明,在文件作用域初始化intCountedObject::count_=100;CountedObject::CountedObject(){++count_;}CountedObject::~CountedObject(){--count_;}intCountedObject::GetCount(){returncount_;}

2.2 访问方式

  • 通过类名加作用域运算符:CountedObject::GetCount()
  • 通过对象或对象指针:co1.GetCount()co2->GetCount()(不推荐,易混淆)

2.3 特点与注意事项

  • 静态数据成员独立于任何对象存在,即使没有创建类对象,它也已分配内存。
  • 所有对象共享同一个静态数据成员。
  • 静态数据成员可以是private,通过公有静态成员函数访问,实现封装。
  • 静态数据成员的名字位于类作用域中,避免与全局变量冲突。

3. 静态成员函数

3.1 特点

  • 静态成员函数没有this指针,因此不能直接访问非静态数据成员或调用非静态成员函数。
  • 非静态成员函数可以任意访问静态数据成员和静态成员函数。
  • 静态成员函数只能访问静态数据成员和其他静态成员函数。

3.2 示例:错误与正确访问

#include<iostream>usingnamespacestd;classTest{public:Test(inty):y_(y){}voidNonStaticFun(){cout<<"非静态函数中访问静态成员 x_ = "<<x_<<endl;StaticFun();// 非静态成员函数可以调用静态成员函数}staticvoidStaticFun(){// NonStaticFun(); // 错误!静态成员函数不能调用非静态成员函数// cout << y_; // 错误!不能访问非静态成员cout<<"静态函数中访问静态成员 x_ = "<<x_<<endl;}private:staticintx_;// 静态数据成员声明inty_;};// 静态数据成员定义及初始化intTest::x_=100;intmain(){Testt(10);t.NonStaticFun();// 输出:非静态函数中访问静态成员 x_ = 100Test::StaticFun();// 输出:静态函数中访问静态成员 x_ = 100// 通过对象访问静态成员(允许但不推荐)cout<<t.x_<<endl;// 100cout<<Test::x_<<endl;// 推荐方式return0;}

4. 静态常量数据成员

static const修饰的静态常量成员,其值不可修改。对于整型intcharbool等)静态常量成员,可以在类内直接初始化(C++11 以后也允许非整型,但推荐统一在类外定义)。

示例

#include<iostream>usingnamespacestd;classTestConst{public:staticconstintkValue=100;// 静态常量整型,可在类内初始化staticconstdoublekPi;// 非整型,只能在类外定义};// 静态常量成员类外定义(不带 static 关键字)constdoubleTestConst::kPi=3.14159;intmain(){cout<<TestConst::kValue<<endl;// 100cout<<TestConst::kPi<<endl;// 3.14159// TestConst::kValue = 200; // 错误:常量不可修改return0;}

5. 综合示例:统计对象个数

以下是一个完整的、可运行的统计某类对象创建与销毁个数的程序。

// CountedObject.h#ifndefCOUNTED_OBJECT_H#defineCOUNTED_OBJECT_HclassCountedObject{public:CountedObject();~CountedObject();staticintGetCount();private:staticintcount_;};#endif
// CountedObject.cpp#include"CountedObject.h"intCountedObject::count_=0;CountedObject::CountedObject(){++count_;}CountedObject::~CountedObject(){--count_;}intCountedObject::GetCount(){returncount_;}
// main.cpp#include"CountedObject.h"#include<iostream>usingnamespacestd;intmain(){cout<<"初始对象数: "<<CountedObject::GetCount()<<endl;// 0CountedObject obj1;CountedObject obj2;cout<<"创建两个对象后: "<<CountedObject::GetCount()<<endl;// 2CountedObject*pObj=newCountedObject;cout<<"动态创建一个对象后: "<<CountedObject::GetCount()<<endl;// 3deletepObj;cout<<"删除动态对象后: "<<CountedObject::GetCount()<<endl;// 2return0;}

6. 重点总结

特性静态数据成员非静态数据成员
存储位置全局数据区,独立于对象每个对象各自的内存空间
初始化类外定义时初始化,仅一次构造函数初始化列表或体内
访问方式类名::成员或 对象.成员只能通过对象或指针访问
能否被静态成员函数访问可以不可以
能否被非静态成员函数访问可以可以
特性静态成员函数非静态成员函数
是否含有this指针
能否访问静态成员可以可以
能否访问非静态成员不可以可以
调用方式类名::函数名或 对象.函数名必须通过对象或指针调用

7. 常见误区与注意事项

  1. 静态成员函数不能调用非静态成员函数,因为非静态成员函数隐含this指针,而静态函数没有。
  2. 静态数据成员不能在类内初始化(除static const整型外),必须在类外单独定义。
  3. 通过对象访问静态成员容易产生误解,建议使用类名::静态成员以明确其属于类。
  4. 静态成员变量即使不创建任何类对象,也已存在并可通过类名访问(如果为public)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 22:44:24

20260413 if while 语句

一、IF 语句 1.1 语法 1.1.1 单分支语法 # 单分支 if 条件判断;thencommand fiif 条件判断 thencommand fi条件判断 && command1.1.2 双分支语法 # 单分支 if 条件判断;thencommand1 elsecommand2 fi条件判断 && command1 || command21.1.3 多分支语法 # 单分支…

作者头像 李华
网站建设 2026/4/14 22:43:37

MathCAD Prime 5.0破解安装全流程:手把手教你搞定许可证和环境变量

MathCAD Prime 5.0 高效安装与配置指南 在工程计算和数学建模领域&#xff0c;MathCAD Prime 5.0 凭借其直观的界面和强大的功能成为众多工程师的首选工具。本文将详细介绍如何快速完成软件的安装与配置&#xff0c;确保您能够顺利开始使用这款专业工具。 1. 准备工作与环境检查…

作者头像 李华
网站建设 2026/4/14 22:37:41

LoRA QLoRA

二者区别QLoRA 弊端

作者头像 李华