一、static的几种用法

1、修饰局部变量(函数内部)

void foo() {
    static int count = 0;
    count++;
    std::cout << count << std::endl;
}

    •    count 只在第一次调用时初始化一次,后续调用保持上次的值。
    •    生命周期贯穿整个程序运行期(静态存储区)。
    •    作用域仍然是函数内(外部不可见)。
用途:函数内部的“状态保持”。

2、修饰全局变量/函数(文件作用域)

static int g_value = 42;
static void helper() {}

•    仅在当前 .cpp 文件可见(内部链接性)。
•    其他文件无法 extern 访问。
用途:隐藏实现细节,避免命名冲突(模块封装)。

3、修饰类的成员变量

class A {
public:
    static int counter;
};
int A::counter = 0; // 需类外定义

•    所有对象共享同一份变量。
•    不依赖对象存在(生命周期随程序)。
用途:类级别的全局状态(如计数器、缓存、注册表等)。


4、修饰类的成员函数

class A {
public:
    static void sayHello() {
        std::cout << "Hello" << std::endl;
    }
};

•    无需实例化即可调用:A::sayHello()
•    无 this 指针,不能访问非静态成员。
用途:
•    工具函数(不依赖对象)
•    工厂方法

二、工厂方法是什么?

“工厂方法”是一种创建型设计模式,用于封装对象创建逻辑,让创建与使用解耦。也就是说不直接 new 对象,而是通过一个“工厂方法”来创建它。

最常见形式

class Shape {
public:
    virtual void draw() = 0;

    // 静态工厂方法
    static Shape* create(const std::string& type) {
        if (type == "circle") return new Circle();
        if (type == "square") return new Square();
        return nullptr;
    }
};

class Circle : public Shape {
public:
    void draw() override { std::cout << "Circle\n"; }
};

class Square : public Shape {
public:
    void draw() override { std::cout << "Square\n"; }
};

// 使用:
Shape* s = Shape::create("circle");
s->draw();
delete s;

•    Shape::create() 是 静态成员函数。
•    它不需要实例就能创建对象。
•    它把 new 的细节隐藏起来,让用户只关心“要什么类型”,而不是“怎么创建”。

三、static和工厂方法的关系

简单的说,工厂方法“经常”被写成 static,但不是必须 static。

四、总结

•    static 是 语言关键字,控制存储周期和作用域;
•    工厂方法是 设计思想,控制对象创建过程;
•    两者常常结合在一起:
•    工厂方法一般声明为 static;
•    这样无需实例化类就能创建对象;
•    提升封装性和可维护性。
 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐