[转]C++ 类中的static成员的初始化和特点
在C++的类中有些成员变量初始化和一般数据类型的成员变量有所不同。以下测试编译环境为:
1 2 3 4 5 | ➜ g++ -v Using built-in specs. COLLECT_GCC=g++ Target: x86_64-linux-gnu gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) |
测试代码(g++编译通过):
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 30 31 | #include <iostream> using namespace std; class Test { public : Test() : y(1), r(y), d(3){} //对于常量型成员变量和引用型成员变量,必须通过参数化列表的方式进行初始化。 ~Test(){} int y; //普通变量成员 int &r; //引用成员变量 const int d; //常量成员变量 static int c; //静态成员变量 static const int x = 2.1; //静态常量整型成员变量 static const int xx; //静态常量整型成员变量声明 static const double z; //静态常量非整型成员变量声明 static const float zz = 6.6; //静态常量非整型成员变量 }; const int Test::xx = 4; //静态常量整型成员变量定义 const double Test::z = 5.1; ////静态常量非整型成员变量定义 int Test::c = 2; int main( void ) { cout << Test::x << endl; return 0; } |
这些特殊类型的成员变量主要有:
1 2 3 4 5 | 1. 引用 2. 常量 3. 静态变量 4. 静态整型常量 5. 静态非整型常量 |
-
对于==1. 引用==和==2. 常量==,成员变量必须通过构造函数的==参数列表==的方式初始化。例如:上述程序中的r 和 d 变量的初始化。
-
对于==3. 静态变量==,static成员变量需要在类定义体外进行初始化与定义,因为static数据成员独立该类的任意对象存在,它是与类关联的对象,不与类对象关联。例如:上述程序中的c变量的初始化。
-
对于==4. 静态整型常量==,该类型成员可以直接在类中初始化,也可以在类中声明,在类定义体外进行定义。例如:上述程序中的x和xx变量。
-
对于==5. 静态非整型常量==,该类型也是可以在类中声明在类定义体外进行定义,或者直接在类中定义初始化。例如:上述程序中的z和zz变量。
结论:
静态成员属于类作用域,但不属于类对象,它的生命周期和普通的静态变量一样,程序运行时进行分配内存和初始化,程序结束时则被释放。所以不能在类的构造函数中进行初始化。
static成员的优点
- static成员的名字是在类的作用域中,因此可以避免与其它类成员或全局对象名字冲突。
- 可以实施封装,static成员可以是私有的,而全局对象不可以。
- 阅读程序容易看出static成员与某个类相关联,这种可见性可以清晰地反映程序员的意图。
static成员函数特点
- 因为static成员函数没有this指针,所以静态成员函数不可以访问非静态成员。
- 非静态成员函数可以访问静态成员。
- 静态数据成员与类的大小无关,因为静态成员只是作用在类的范围而已。
123456789101112131415161718192021222324252627282930313233
#include <iostream>
using
namespace
std;
class
test2
{
public
:
test2(
int
num) : y(num){}
~test2(){}
static
void
testStaticFun()
{
cout <<
"y = "
<< y << endl;
//Error:静态成员函数不能访问非静态成员
}
void
testFun()
{
cout <<
"x = "
<< x << endl;
}
private
:
static
int
x;
//静态成员变量的引用性说明
int
y;
};
int
test2::x = 10;
//静态成员变量的定义性说明
int
main(
void
)
{
test2 t(100);
t.testFun();
return
0;
}
static用法总结
- c语言中:
- 用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期长于该函数,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的,比如strtok(3)。
- 用在文件级别(函数体之外),修饰变量或函数,表示该变量或函数只在本文件可见,其他文件看不到也访问不到该变量或函数。专业的说法叫“具有internal linkage”(简言之:不暴露给别的translation unit)。
- c++语言中(由于C++引入了类,在保持与C语言兼容的同时,static关键字又有了两种新用法):
- 用于修饰类的数据成员,即所谓“静态成员”。这种数据成员的生存期大于class的对象(实例/instance)。静态数据成员是每个class有一份,普通数据成员是每个instance 有一份。
- 用于修饰class的成员函数,即所谓“静态成员函数”。这种成员函数只能访问静态成员和其他静态程员函数,不能访问非静态成员和非静态成员函数。
- c语言中:
分类:
C++学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架