一.static 关键字
在C++中,关键字 static
有多种用法,它可以用于不同的上下文中,具体取决于它所修饰的对象或变量。以下是一些常见的用法:
1.静态变量 (Static Variables): 在函数内部或全局作用域中声明的静态变量在程序的整个生命周期内保持其值。与普通局部变量不同,静态变量只会在首次进入其作用域时初始化一次。例如:
- 局部静态变量:
- 存储:全局数据区
- 生命周期:在整个程序结束之前都存在
- 作用域:被定义的函数内
#include <iostream>
void foo() {
static int count = 0; // 静态局部变量
count++;
std::cout << "Count: " << count << std::endl;
}
int main() {
foo();
foo();
return 0;
}
- 全局静态变量:
- 存储:全局数据区
- 生命周期:整个程序结束之前
- 作用域:定义该变量的文件未被 include 时:仅限于被定义的文件内;被 include 后,include 定义变量的文件的文件可以直接使用此变量
2. 静态函数 (Static Functions)
静态函数 优点:
- 仅限于在被定义的文件内使用
- 可以和其他文件的函数同名
面向对象中的static
静态成员变量:
作为类的成员,不论这个类被定义多少次,只有一份拷贝。(也就是只分配一次内存,供所有此类的对象使用)
- 存储:全局数据区
- 初始化:类外初始化(原因:此变量属于类,类内初始化会初始化对象时矛盾)
- 变量类型 类名::静态成员变量=值;
- 访问:
- 类名::变量;
- 对象名.变量;
- 优点:
- 静态成员变量名没有进入程序的全局名字空间,所以不会和其他全局变量重名。
- 静态成员变量可以是 private 成员,而全局变量不行
静态成员函数:
- 静态成员之间可以相互访问,包括静态成员函数可以访问静态成员变量和其他静态成员函数。
- 非静态成员函数可以任意的访问静态成员函数和静态成员变量。
- 静态成员函数不能访问非静态成员变量和非静态成员函数。
- 没有 this 指针的额外开销,因此静态成员函数与类的全局函数相比速度上有少许增长。
- 调用:
- 类名::静态成员函数名()
- 对象名.静态成员函数名()
4.静态类 (Static Classes): 在C++中,可以将类声明为静态类,这意味着无法创建该类的实例,通常用于包含静态成员和静态函数的类。
class StaticClass {
public:
static void staticFunction() {
std::cout << "This is a static function in a static class." << std::endl;
}
};
int main() {
// 无法创建StaticClass的实例
// StaticClass myObj; // 这将导致编译错误
StaticClass::staticFunction(); // 直接调用静态函数
return 0;
}
拓展:全局变量和局部变量
- 全局变量:
- 存储:全局数据区
- 生命周期:整个程序的生命周期
- 作用域:在定义该变量的文件内直接使用,其他文件中需要 使用 extern 去进行声明,也可以使用。
- 局部变量:
- 存储:栈区
- 生命周期:被定义的函数的声明周期
- 作用域:被定义的函数内
三.const 关键字
在C++中,const
是一个关键字,用于声明常量或表明某些东西是不可修改的。const
可以应用于不同的上下文,包括变量、函数参数和成员函数。以下是关于C++中的 const
的一些常见用法:
1.常量变量 (Constant Variables): 使用 const
关键字声明的变量是常量,它们的值在初始化后不能被修改。
const int myConstVar = 10;
// myConstVar = 20; // 这将导致编译错误,常量不能被修改
2.指向常量的指针 (Pointers to Constants): 使用 const
修饰指针,可以创建指向常量的指针,这意味着通过该指针不能修改指向的值。
const int myConstVar = 10;
const int* ptr = &myConstVar;
// *ptr = 20; // 这将导致编译错误,通过 ptr 不能修改 myConstVar 的值
3.常量指针 (Constant Pointers): 使用 const
修饰指针变量本身,可以创建一个常量指针,这意味着该指针不能指向其他变量,但可以用来修改指向的值。
int myVar = 10;
int* const ptr = &myVar;
*ptr = 20; // 有效,可以修改 myVar 的值
// ptr = nullptr; // 这将导致编译错误,不能修改 ptr 指向其他地址
4.常量成员函数 (Constant Member Functions): 在类中的成员函数前面加上 const
关键字,表示该函数不会修改对象的状态。它可以被用于常量对象上。
class MyClass {
public:
void normalFunction() {
// 可以修改对象的成员变量
}
void constFunction() const {
// 不能修改对象的成员变量
}
};
const MyClass constObj;
constObj.normalFunction(); // 这将导致编译错误
constObj.constFunction(); // 可以调用 const 成员函数
5.常引用 (Constant References): 使用 const
修饰引用,可以创建常量引用,这意味着通过该引用不能修改引用的值。
int myVar = 10;
const int& myConstRef = myVar;
// myConstRef = 20; // 这将导致编译错误,不能通过 myConstRef 修改 myVar 的值
6.常量函数参数 (Constant Function Parameters): 在函数参数中使用 const
关键字,表示该参数是常量,函数内部不能修改它的值。
void myFunction(const int x) {
// x = 20; // 这将导致编译错误,x 是常量
}
四.static 和 const 的区别
在C++中,static
和 const
都是关键字,但它们用于不同的目的,具有不同的作用。以下是它们之间的主要区别:
-
作用领域:
static
通常用于控制存储持续性(存储期)和作用域。它可以用于变量、函数、类成员、类本身等,用于控制它们的生命周期和可见性。const
用于声明常量或表示某些东西是不可修改的。它可以应用于变量、函数参数、成员函数等,用于指定不可更改的值或状态。
-
存储期:
static
与存储期相关,它可以使变量成为静态存储期(在程序生命周期内存在)或限制变量的作用域(在某个范围内可见)。const
与存储期无关,它只是指示一个值是常量,无论其存储期如何。
-
可修改性:
static
关键字本身不表示可修改性。它主要用于控制变量的生命周期和作用域,而不是变量本身的可修改性。const
关键字用于表示值是不可修改的。如果你将其应用于变量,那么该变量的值不能被更改。如果你将其应用于函数参数,那么函数不能修改参数的值。
-
示例:
- 使用
static
的示例: -
static int counter = 0; // 静态变量,存储期在整个程序生命周期内 void foo() { static int localVar = 0; // 静态局部变量,作用域在函数内,但存储期在整个程序生命周期内 }
- 使用
const
的示例: -
const int myConstVar = 10; // 常量变量,值不能被修改 void myFunction(const int x) { // 常量函数参数,参数值不能被修改 // x = 20; // 这将导致编译错误,x 是常量 }
总结来说,
static
用于控制存储期和作用域,而const
用于表示不可修改的值或状态。它们在C++中有不同的用途,但可以一起使用,例如声明静态常量或静态成员函数,以实现各种编程需求。