c++ 静态变量 静态函数

1. 静态成员变量

1.1 简介

静态成员变量(static member variable)是属于类而不是类的实例的成员变量。它们在类的所有实例之间共享,只有一个副本存在于内存中。静态成员变量使用 static 关键字进行声明和定义,并且必须在类的外部进行初始化。

1.2 特点

  1. 静态成员变量在程序运行期间只会被初始化一次
  2. 所有对象共享相同的值:无论创建多少个对象,它们都会共享同一个静态成员变量的值。
  3. 存储于静态数据区:静态成员变量的内存分配发生在静态数据区,而不是在对象的内存中。它们在程序运行期间存在,直到程序结束。
  4. 可以通过类名和对象访问:静态成员变量可以通过类名直接访问,也可以通过对象访问。对于所有对象来说,它们都是相同的。

代码:

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class MyClass {
public:
    static int count;  // 声明静态成员变量

    MyClass() {
        std::cout << "MyClass()  Count: " << count << std::endl;
        count++;  // 在构造函数中对静态成员变量进行操作
    }

    static void printCount() {
        std::cout << "Count: " << count << std::endl;  // 在静态成员函数中访问静态成员变量
    }
};

int MyClass::count = 0;  // 静态成员变量的定义和初始化

int main() {
    MyClass obj1;
    obj1.printCount();

    MyClass obj2;
    MyClass::printCount();  // 通过类名访问静态成员函数
    obj1.printCount();      // 通过对象访问静态成员函数
    obj2.printCount();

    return 0;
}

运行结果:

bash 复制代码
MyClass()  Count: 0
Count: 1
MyClass()  Count: 1
Count: 2
Count: 2
Count: 2

1.3 使用场景

  1. 共享数据:如果多个对象需要共享某个值,可以将该值定义为静态成员变量。比如统计一个类的对象数量或记录全局状态等。
  2. 类常数:将常用且不会改变的值定义为静态成员变量,方便在类内外使用,并节省内存空间。
  3. 跨对象操作:当需要在多个对象之间进行协作或共享资源时,可以使用静态成员变量来实现数据传递和共享。

静态成员变量适合用于需要在多个对象之间共享数据或保存全局状态的情况下使用。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class DatabaseConnection {
private:
    static int connectionCount; // 静态成员变量,用于记录连接数

public:
    DatabaseConnection() {
        connectionCount++;
        std::cout << "New database connection established." << " " << connectionCount << std::endl;
    }

    ~DatabaseConnection() {
        connectionCount--;
        std::cout << "Database connection closed." << " " << connectionCount << std::endl;
    }

    static int getConnectionCount() {
        return connectionCount;
    }
};

int DatabaseConnection::connectionCount = 0;

int main() {
    DatabaseConnection conn1;
    std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;
    std::cout << "------------------------------------ " <<std::endl;
    {
        DatabaseConnection conn2;
        DatabaseConnection conn3;
        std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;
    }
    std::cout << "------------------------------------ " <<std::endl;
    std::cout << "Total database connections: " << DatabaseConnection::getConnectionCount() << std::endl;

    return 0;
}

运行结果:

cpp 复制代码
New database connection established. 1
Total database connections: 1
------------------------------------ 
New database connection established. 2
New database connection established. 3
Total database connections: 3
Database connection closed. 2
Database connection closed. 1
------------------------------------ 
Total database connections: 1
Database connection closed. 0

2. 静态函数

2.1 简介

静态函数(或称为静态成员函数)(static member function)是属于类而不是对象的成员函数。它们通过在函数声明前面使用 static 关键字进行标识。

2.2 特点

  1. 静态函数可以直接通过类名调用,无需创建类的对象。
  2. 静态函数不能访问非静态成员变量和非静态成员函数,因为它们没有隐式的 this 指针。
  3. 静态函数不能被声明为虚函数,因为虚函数需要动态绑定。
  4. 静态函数的作用范围限定在所属的类中,无法直接访问类的私有成员,除非它们是该类的友元函数。

2.3 使用场景

  1. 实现工具函数或辅助功能
    静态函数常用于实现一些与类的状态无关的工具函数或辅助功能。例如,计算两个整数之和可以使用一个静态函数:
cpp 复制代码
#include <iostream>

class MathUtils {
public:
    static int max(int a, int b) {
        return (a > b) ? a : b;
    }

    static int min(int a, int b) {
        return (a < b) ? a : b;
    }
};

int main() {
    int num1 = 10;
    int num2 = 5;

    int maximum = MathUtils::max(num1, num2);  // 使用静态函数计算最大值
    int minimum = MathUtils::min(num1, num2);  // 使用静态函数计算最小值

    std::cout << "Maximum: " << maximum << std::endl;
    std::cout << "Minimum: " << minimum << std::endl;

    return 0;
}

通过使用静态函数,可以将一些通用的功能与类相关联,而无需创建类的实例。这样可以提高代码的可读性和可维护性。

  1. 访问私有静态成员变量

如果想在类的外部访问私有静态成员变量,可以通过公有的静态成员函数来实现。这样做可以控制对私有数据的访问,并提供统一接口。

代码:

cpp 复制代码
class Counter {
private:
    static int count_;

public:
    static void increment() {
        count_++;
    }

    static int getCount() {
        return count_;
    }
};

int Counter::count_ = 0;

int main() {
    Counter::increment();
    Counter::increment();

    // 输出结果为2
    std::cout << Counter::getCount() << std::endl;

    return 0;
}
  1. 创建单例模式
    静态函数常用于创建单例模式,确保只有一个实例被创建并全局访问。
cpp 复制代码
class Singleton {
private:
    static Singleton* instance_;

    // 私有构造函数,禁止外部创建对象
    Singleton() {}

public:
    static Singleton* getInstance() {
        if (instance_ == nullptr) {
            instance_ = new Singleton();
        }
        return instance_;
    }
};

Singleton* Singleton::instance_ = nullptr;

int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();

    // 输出结果为1,说明只有一个实例被创建
    std::cout << (s1 == s2) << std::endl;

    return 0;
}
  1. 在某些设计模式中,如工厂模式、策略模式等,用于创建对象或执行特定算法。
    静态函数还常用于实现工厂方法模式,即通过静态函数创建类的实例并返回。
cpp 复制代码
#include <iostream>

class Shape {
public:
    virtual void draw() = 0;
    static Shape* createShape(int type);

    // 其他成员函数...
};

class Circle : public Shape {
public:
    void draw() {
        std::cout << "Drawing a circle." << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() {
        std::cout << "Drawing a rectangle." << std::endl;
    }
};

Shape* Shape::createShape(int type) {
    if (type == 1)
        return new Circle();
    else if (type == 2)
        return new Rectangle();
    else
        return nullptr;
}

int main() {
    Shape* shape1 = Shape::createShape(1);  // 使用静态函数创建圆形
    Shape* shape2 = Shape::createShape(2);  // 使用静态函数创建矩形

    shape1->draw();
    shape2->draw();

    delete shape1;
    delete shape2;

    return 0;
}
  1. 在多线程编程中,可以将静态函数作为线程入口点。

总结,静态函数是属于类而不是对象的成员函数,并且其调用方式和访问权限有所限制。适合在不依赖于特定对象状态或需要全局可访问性的情况下使用。

相关推荐
轻口味7 分钟前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学1 小时前
QT-简单视觉框架代码
开发语言·qt
威桑1 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服1 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生1 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans1 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
Chinese Red Guest2 小时前
python
开发语言·python·pygame
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言