c++ 静态成员+单件模式 事件

1.概要

起因:很多时候类都是需要单件的,可以用静态的方式类解决。但用单件有些情况效果更到。

我起初想用静态构造函数来做静态成员的初始化,但是没有成功,所以使用了这个例子。

其实理想的方式是在静态构造函数内对静态成员初始化。

2.代码

#include <iostream>
#include "A.h"

int main()
{
    int b = A::getMy()->fun(5);
    std::cout << b<<"\n";
    std::cout << "Hello World!\n";
}
#pragma once
class A
{
public:
	int fun(int a);
	static A* myF;
	static int a;
	static A* getMy();
};

#include "A.h"

int A::a = 1;
A* A::myF = 0;
int A::fun(int a) {
	return a * a;
}

A* A::getMy() {
	if (myF == 0) {
		myF = new A();
	}
	return myF;
}

3.运行结果 

4.补充说明

 4.1 c++ 静态成员变量

在C++中,静态成员变量(也称为类变量或静态类成员)是类的所有实例(对象)共享的变量。这意味着无论创建了多少个类的对象,都只有一个静态成员变量的副本。静态成员变量在类的所有实例之间都是相同的,并且在类的作用域内是可访问的。

静态成员变量的一些特点:

  1. 静态存储期:静态成员变量具有静态存储期,这意味着它们的生命周期与整个程序相同。
  2. 类作用域:静态成员变量属于类,而不属于类的任何对象。因此,它们可以通过类名和作用域解析运算符(::)来访问,而无需创建类的对象。
  3. 初始化:静态成员变量必须在类外部进行初始化,并且只能初始化一次。

下面是一个示例,展示了如何在C++中定义和使用静态成员变量:

#include <iostream>  
  
class MyClass {  
public:  
    // 声明静态成员变量  
    static int count;  
  
    // 构造函数,每次创建对象时增加计数  
    MyClass() {  
        count++;  
    }  
  
    // 静态成员函数,用于访问静态成员变量  
    static void printCount() {  
        std::cout << "Objects created: " << count << std::endl;  
    }  
};  
  
// 在类外部初始化静态成员变量  
int MyClass::count = 0;  
  
int main() {  
    MyClass obj1;  // count 现在为 1  
    MyClass::printCount();  // 输出 "Objects created: 1"  
  
    MyClass obj2;  // count 现在为 2  
    MyClass::printCount();  // 输出 "Objects created: 2"  
  
    return 0;  
}

在上面的示例中,我们定义了一个名为MyClass的类,该类具有一个静态成员变量count和一个静态成员函数printCount()。我们在类外部初始化了静态成员变量count,并在构造函数中每次创建对象时增加其值。我们还使用静态成员函数来访问静态成员变量并打印其值。

 4.2 c++ 静态类成员

在C++中,静态类成员(包括静态成员变量和静态成员函数)是与类关联但与类的任何特定对象实例无关的成员。静态类成员在类的所有实例之间共享,并且可以通过类名和作用域解析运算符::来访问,而不需要类的实例。

静态成员变量

静态成员变量在类的所有实例之间共享其值。静态成员变量在类的定义之外进行定义和初始化。下面是一个示例:

 
#include <iostream>  
  
class MyClass {  
public:  
    // 声明静态成员变量  
    static int count;  
  
    // 构造函数  
    MyClass() {  
        // 构造函数中更新静态成员变量  
        count++;  
    }  
  
    // 其他成员函数...  
};  
  
// 在类外部定义并初始化静态成员变量  
int MyClass::count = 0;  
  
int main() {  
    MyClass obj1;  // count 现在为 1  
    MyClass obj2;  // count 现在为 2  
    std::cout << "Objects created: " << MyClass::count << std::endl;  // 输出 "Objects created: 2"  
  
    return 0;  
}

静态成员函数

静态成员函数是类的成员函数,但它只能访问静态成员变量和其他静态成员函数。静态成员函数不能直接访问类的非静态成员变量或非静态成员函数,因为非静态成员是与类的特定实例关联的。

下面是一个示例,其中包含一个静态成员函数来访问静态成员变量:

#include <iostream>  
  
class MyClass {  
public:  
    // 声明静态成员变量  
    static int count;  
  
    // 声明静态成员函数  
    static void printCount() {  
        std::cout << "Objects created: " << count << std::endl;  
    }  
  
    // 构造函数  
    MyClass() {  
        count++;  
    }  
  
    // 其他成员函数...  
};  
  
// 在类外部定义并初始化静态成员变量  
int MyClass::count = 0;  
  
int main() {  
    MyClass obj1;  
    MyClass::printCount();  // 输出 "Objects created: 1"  
  
    MyClass obj2;  
    MyClass::printCount();  // 输出 "Objects created: 2"  
  
    return 0;  
}

使用场景

静态类成员常用于以下场景:

  • 需要跟踪类创建的对象数量时(如上述示例中的count)。
  • 当一个函数只需要访问类的静态数据时(如工厂函数或工具函数)。
  • 当一个函数只需要访问类的静态状态,而不需要访问或修改类的任何非静态成员时。

请注意,静态成员函数没有this指针,因为它们不与类的特定实例关联。因此,静态成员函数不能访问或修改类的非静态成员(除非它们作为参数显式传递)。

4.3 c++ 静态成员变量是自定义类型 

在C++中,静态成员变量也可以是自定义类型(即类类型或结构体类型)。当静态成员变量是自定义类型时,你需要在类外部为其分配内存并构造(如果需要的话)。这通常涉及到使用类的构造函数来初始化静态成员变量。但是,对于静态成员变量,你不能直接在类定义中调用构造函数,因为静态成员变量不属于任何类的特定实例。

然而,你可以使用一种称为“局部静态变量初始化”的技巧来在第一次访问静态成员变量时为其分配内存和构造。这种方法利用了C++中局部静态变量在首次进入其定义的作用域时初始化的特性。

以下是一个示例,展示了如何在C++中使用自定义类型的静态成员变量:

#include <iostream>  
  
class MyCustomType {  
public:  
    int value;  
  
    MyCustomType(int v) : value(v) {}  
  
    void printValue() const {  
        std::cout << "Value: " << value << std::endl;  
    }  
};  
  
class MyClass {  
public:  
    // 声明静态成员变量,类型为MyCustomType  
    static MyCustomType staticMember;  
  
    // 静态成员函数,用于访问静态成员变量  
    static void printStaticMember() {  
        staticMember.printValue();  
    }  
  
    // 注意:我们不在类定义中初始化staticMember  
};  
  
// 在类外部定义并初始化静态成员变量  
// 注意这里我们使用了一个匿名命名空间来确保只初始化一次  
namespace {  
    MyCustomType& initStaticMember() {  
        static MyCustomType instance(42); // 初始化静态成员变量  
        return instance;  
    }  
}  
  
// 使用函数初始化的技巧来初始化静态成员变量  
MyCustomType& MyClass::staticMember = initStaticMember();  
  
int main() {  
    MyClass::printStaticMember(); // 输出 "Value: 42"  
    return 0;  
}

在上面的示例中,我们使用了一个匿名命名空间中的initStaticMember函数来初始化MyClass::staticMember。这个函数返回一个对局部静态变量instance的引用,该变量在第一次调用initStaticMember时被构造。由于initStaticMember函数只在MyClass::staticMember的定义中被调用一次,因此instance也只会被构造一次。

这种方法的优点是它允许你在类外部控制静态成员变量的初始化,并且可以处理更复杂的初始化逻辑(例如,可能需要调用其他函数或进行条件检查)。然而,它也增加了代码的复杂性,因此应该谨慎使用。在大多数情况下,如果静态成员变量的初始化很简单,直接在类外部进行初始化就足够了。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值