1. 函数内static局部变量:变量在程序初始化时被分配,直到程序退出前才被释放,也就是static是按照程序的生命周期来分配释放变量的,而不是变量自己的生命周期。多次调用,仅需一次初始化。
2. cpp内的static全局变量:只在cpp内有效。在不同的cpp文件中定义同名变量,不必担心命名冲突。保持变量内容的持久。
3. 头文件内的static全局变量:在每个包含该头文件的cpp文件中都是独立的。不推荐使用。
4. static函数:仅在当前文件内有效。在不同的cpp文件中定义同名函数,不必担心命名冲突。对其它源文件隐藏。在现代C++中被无名namespace取代。
5. 类的static数据成员:必须在class的外部初始化。
6. 类的static函数:不能访问类的私有成员,只能访问类的static成员,不需要类的实例即可调用。可以继承和覆盖,但无法是虚函数。属于整个类而非类的对象,没有this指针。静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数。非静态成员函数可以任意地访问静态成员函数和静态数据成员。静态成员函数不能访问非静态成员函数和非静态数据成员。
7. 单例模式(Singleton)中使用static:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
以下是测试代码:
static.hpp:
#ifndef FBC_CPP_BASE_TEST_STATIC_HPP_
#define FBC_CPP_BASE_TEST_STATIC_HPP_
#include <iostream>
namespace static_ {
class A {
public:
static int func(); // 只能调用静态成员
int func2();
public:
static int val;
private:
int val2 = 5;
static int val3; // 必须在类外进行初始化
};
struct X {
private:
int i;
static int si;
public:
void set_i(int arg) { i = arg; }
static void set_si(int arg) { si = arg; }
void print_i() {
std::cout << "Value of i = " << i << std::endl;
std::cout << "Again, value of i = " << this->i << std::endl;
}
static void print_si() {
std::cout << "Value of si = " << si << std::endl;
// A static member function does not have a this pointer
//std::cout << "Again, value of si = " << this->si << std::endl; // error
}
};
class C {
// A static member function cannot be declared with the keywords virtual, const, volatile, or const volatile.
// A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared.
static void f() {
std::cout << "Here is i: " << i << std::endl;
}
static int i;
int j;
public:
C(int firstj) : j(firstj) { }
void printall();
};
class Singleton {
public:
static Singleton& Instance();
private:
Singleton(); // Singleton不可以被实例化,因此将其构造函数声明为protected或者直接声明为private
};
int test_static_1();
int test_static_2();
int test_static_3();
int test_static_4();
int test_static_5();
int test_static_6();
int test_static_7();
} // namespace static_
#endif // FBC_CPP_BASE_TEST_STATIC_HPP_
static.cpp:
#include "static.hpp"
#include <iostream>
namespace static_ {
///
static size_t count_calls()
{
// 局部静态对象(local static object)在程序的执行路径第一次经过对象定义
// 语句时初始化,并且直到程序终止才被销毁,在此期间即使对象所在的函数结
// 束执行也不会对它有影响。
static size_t ctr = 0; // 调用结束后,这个值仍然有效
return ++ctr;
}
int test_static_1()
{
for (int i = 0; i < 10; ++i) {
fprintf(stdout, "ctr: %d\n", count_calls());
}
return 0;
}
/
int A::val = 10;
int A::val3 = 15;
int A::func()
{
return ++val3;
}
int A::func2()
{
return (val3 + val2 + func());
}
int test_static_2()
{
fprintf(stdout, "A::val: %d\n", A::val);
for (int i = 0; i < 5; ++i)
fprintf(stdout, "A::func: %d\n", A::func());
A a;
fprintf(stdout, "a.func2: %d\n", a.func2());
return 0;
}
static int xx = 5;
int test_static_3()
{
fprintf(stdout, "xx: %d\n", xx);
return 0;
}
///
// reference: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr039.htm
int X::si = 77; // Initialize static data member
int test_static_4()
{
X xobj;
xobj.set_i(11);
xobj.print_i();
// static data members and functions belong to the class and
// can be accessed without using an object of class X
X::print_si();
X::set_si(22);
X::print_si();
return 0;
}
//
// reference: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr039.htm
void C::printall() {
std::cout << "Here is j: " << this->j << std::endl;
// You can call a static member function using the this pointer of a nonstatic member function
this->f();
}
int C::i = 3;
int test_static_5()
{
C obj_C(2);
obj_C.printall();
return 0;
}
/
// reference: https://msdn.microsoft.com/en-us/library/y5f6w579.aspx
void showstat(int curr)
{
static int nStatic; // Value of nStatic is retained between each function call
nStatic += curr;
std::cout << "nStatic is " << nStatic << std::endl;
}
int test_static_6()
{
for (int i = 0; i < 5; i++)
showstat(i);
return 0;
}
///
Singleton::Singleton()
{
std::cout << "constructor Singleton ..." << std::endl;
}
Singleton& Singleton::Instance()
{
static Singleton _instance;
return _instance;
}
int test_static_7()
{
Singleton& sgn1 = Singleton::Instance();
Singleton& sgn2 = Singleton::Instance();
if (&sgn1 == &sgn2) std::cout << "ok" << std::endl;
else std::cout << "no" << std::endl;
return 0;
}
} // namespace static_
GitHub:
https://github.com/fengbingchun/Messy_Test