静态成员变量需在类外定义初始化,类内仅声明;静态成员函数无this指针,只能访问静态成员,不可直接访问非静态成员。
类内声明 static 成员变量只是声明,不分配内存;真正分配内存和初始化必须在类外完成,否则链接时会报 undefined reference to 'ClassName::staticVar'。
class Counter {
public:
static int count;
};.cpp 文件中必须定义(且仅一次):int Counter::count = 0;
inline C++17 起支持),否则易引发 ODR 违规static 成员函数没有 this 指针,因此不能访问非静态数据成员或调用非静态成员函数。它本质是“属于类的普通函数”,只是作用域受限于类名。
class Logger {
public:
static int level;
static void setLevel(int l) { level = l; } // ✅ 只访问 static 成员
static void log(const char* msg) { printf("[%d] %s\n", level, msg); }
};static void bad() { value++; } // ❌ 'value' 是非静态成员,编译报错static void inspect(const MyClass& obj) { std::cout << obj.data; }静态成员变量是全局共享的,多个线程并发读写时极易引发数据竞争。C++ 不自动加锁,必须由程序员显式同步。
std::atomic 替代普通类型:class Counter {
public:
static std::atomic count;
};
std::atomic Counter::count{0}; // 初始化 std::mutex 或 std::shared_mutex
派生类会继承基类的静态成员,但每个类拥有独立副本(除非显式使用基类作用域访问)。静态成员不参与多态,也不存在“虚静态函数”。
class Base { public: static
int x; };
class Derived : public Base { public: static int x; }; // 这是另一个 x,不是覆盖Base::x 访问virtual 修饰;试图重写只会隐藏(hiding),而非覆盖(overriding)MyClass::val 和 MyClass::val 完全无关静态成员的本质是“带类作用域的全局实体”。它的便利性来自共享,危险性也源于共享——是否需要跨实例通信、是否会被并发修改、是否要被继承复用,这些才是决定用不用静态成员的关键,而不是“图个方便”。