前言:
在C++中,静态成员变量、静态成员函数和静态常量是非常有用的特性,它们可以方便地组织数据和操作,并提高代码的效率和可读性。本文将介绍静态成员变量、静态成员函数和静态常量的特性、应用及单例模式、工厂模式的实现。
一、C++中静态成员
在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字 static 声明为静态的,称为静态成员。 不管这个类创建了多少个对象,静态成员只 有一个拷贝,这个拷贝被所有属于这个类的对象共享。
1.静态成员变量
静态成员变量是类的成员变量,它们不属于任何对象,也不包含在类的对象分配空间中。静态成员变量只有一份,可以在多个对象之间共享,通常用于表示全局性质的数据,比如计数器、标识符等。
静态成员变量的定义和普通成员变量的定义类似,但需要在变量名前面加上static关键字。在静态成员变量的定义中,不需要加上static关键字,但必须要有类型和名字。
以下是一个静态成员变量的定义示例:
class MyClass {
public:
static int m_staticVar;
};
int MyClass::m_staticVar = 0;
在上述代码中,我们定义了一个名为MyClass的类,它包含一个公有的静态成员变量m_staticVar。在类外部,我们需要对其进行定义和初始化。
静态成员变量可以通过类名或者对象名来引用。对于通过类名引用的静态成员变量,需要加上作用域运算符,比如MyClass::m_staticVar。对于通过对象名引用的静态成员变量,也需要加上作用域运算符,比如myObject.m_staticVar。
int main() {
// 通过类名来访问静态成员变量
MyClass::m_staticVar = 10;
// 创建对象来访问静态成员变量
MyClass myObject;
myObject.m_staticVar = 20;
// 输出静态成员变量的值
cout << MyClass::m_staticVar << endl; // 20
cout << myObject.m_staticVar << endl; // 20
return 0;
}
2.静态常量
静态常量是指在程序运行期间不会改变的(值不能改变)、可以在全局范围内使用的常量。在C++中,我们可以使用静态成员变量来定义静态常量。静态常量与类的实例化无关,只有一份,可以在多个对象之间共享,比如定义数学常数、文件路径等。
由于静态常量和静态变量很相似(只是值是固定的),为了区分于静态变量,最好在类内部就进行初始化。
以下是一个使用静态成员变量定义静态常量的示例代码:
class MyClass {
public:
static const float PI= 3.1415926;
};
在上述代码中,我们定义了一个名为MyClass的类,它包含一个公有的静态成员常量PI。在类内部,我们将其初始化为3.1415926。
静态常量可以通过类名或者对象名来引用。对于通过类名引用的静态常量,需要加上作用域运算符,比如MyClass::PI。对于通过对象名引用的静态常量,也需要加上作用域运算符,比如myObject.PI。(由于使用和静态变量无区别,这里就不作演示)
3.静态成员函数
静态成员函数是类的成员函数,它们不属于任何对象,可以直接通过类名调用。静态成员函数通常用于执行全局性质的操作,比如工厂函数、单例模式等。
静态成员函数的定义和普通成员函数的定义类似,但需要在函数名前面加上static关键字。静态成员函数只能访问静态变量,不能访问普通成员变量 静态成员函数的使用和静态成员变量一样 静态成员函数也有访问权限,普通成员函数可访问静态成员变量、也可以访问非经常成员变量。
以下是一个静态成员函数的定义示例:
#include <iostream>
using namespace std;
class MyClass {
public:
// 普通成员函数可以访问 static 和 non-static 成员属性
void changeParam1(int param) {
mParam = param;
sNum = param;
}
// 静态成员变量和函数只能访问 static 成员属性
static int sNum;
static void changeParam2(int param) {
sNum = param;
}
private:
int mParam;
};
// 定义静态成员变量
int MyClass::sNum = 0;
int main() {
// 通过类名来访问静态成员变量和函数
MyClass::sNum = 10; // 修改静态成员变量
MyClass::changeParam2(20); // 调用静态成员函数
cout << MyClass::sNum << endl; // 20
// 创建对象来访问非静态成员
MyClass obj;
obj.changeParam1(30); // 修改非静态成员变量
cout << obj.sNum << endl; // 20
return 0;
}
在上述代码中,我们定义了一个名为MyClass的类,它包含一个非静态成员变量mParam和两个静态成员函数changeParam2和changeParam3。
在公有区域中,我们定义了一个静态成员变量sNum,并在类外部对其进行初始化。我们还实现了一个通过对象调用的普通成员函数changeParam1,在函数中修改了非静态和静态成员变量的值。
在main函数中,我们通过类名来访问静态成员变量和静态成员函数,并演示了如何使用对象来访问非静态成员变量和非静态成员函数。
二、结合软件设计模式
软件设计模式是关于如何解决软件设计中常见问题的一种共享经验的方式。它是指在面向对象软件设计中,经常遇到的一些重复出现的问题,以及这些问题的解决方案。这些解决方案经过验证,已经被广泛认可,成为了软件设计中的一种最佳实践方法。
软件设计模式的主要目的是提高代码的可重用性、可维护性和可拓展性。通过使用设计模式,开发人员可以将代码分为一系列职责单一的类,让每个类专注于完成自己的任务,从而提高代码的可读性和可维护性。此外,设计模式还可以降低系统的复杂性,提高代码的灵活性和适应性,便于应对系统的变化。
另外,设计模式还可以促进系统的标准化和规范化。由于设计模式是经过验证的最佳实践方法,因此可以被广泛应用到各种项目中,促进开发人员之间的交流,提高开发效率和代码质量。
总而言之,软件设计模式是为了解决复杂问题而定义的一组可重用的解决方案,通过使用这些解决方案,可以提高软件系统的可维护性,可拓展性和可读性,减少代码错误和重复编写。
下面简单列举一些常见的软件设计模式:(仅作参考)
-
工厂模式(Factory Pattern):根据需求返回一个特定类的新对象,而无需知道该类的具体实现细节。
-
单例模式(Singleton Pattern):确保一个类仅有一个对象,并提供全局访问该对象的方法。
-
观察者模式(Observer Pattern):定义对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖该对象的对象都会被通知并自动更新。
-
适配器模式(Adapter Pattern):将两个不兼容的接口转换成可兼容的接口。
-
策略模式(Strategy Pattern):定义一族算法,封装每个算法,并使它们可以相互替换,使得算法可以在运行时独立于使用它的客户而变化。
-
责任链模式(Chain of Responsibility Pattern):将请求的发送者和接收者解耦,并使多个对象都有机会处理这个请求。
-
模板方法模式(Template Method Pattern):定义算法框架,并允许子类为一个或多个步骤提供具体实现。
-
外观模式(Facade Pattern):提供一个简单的接口,隐藏系统的复杂性,使得客户端可以更容易地使用系统。
-
装饰者模式(Decorator Pattern):动态地将责任附加到对象上,扩展对象的功能而不影响其接口。
-
建造者模式(Builder Pattern):将一个复杂对象的构造过程与其表示分离,使得同样的构造过程可以创建不同的表示形式。
以上仅作了解,本文主要结合单例模式和工厂模式下静态成员的演示。
1.单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
在单例模式中,我们通常使用静态成员变量来存储唯一的实例,并使用静态成员函数来获取这个实例。这样可以避免在系统中创建多个相同的对象实例,节约系统资源,并方便全局访问实例。
以下是一个使用静态成员变量实现单例模式的示例代码:
class Singleton {
private:
static Singleton* m_instance;
Singleton() {}
public:
static Singleton* getInstance() {
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
};
Singleton* Singleton::m_instance = nullptr;
在上述代码中,我们定义了一个名为Singleton的类,它包含私有的静态成员变量m_instance和公有的静态成员函数getInstance。在getInstance函数中,我们检查m_instance是否为空,如果为空则创建实例,否则返回现有实例。
2.工厂模式
工厂模式是一种常用的软件设计模式。在它的核心结构中包含一个工厂类,该类提供一个创建对象的方法,用于解耦对象的创建和使用。
在工厂模式中,我们通常使用静态成员函数来创建和返回对象实例。这样可以将对象实例的创建和使用解耦,降低系统的复杂度,并提高代码的可维护性和扩展性。
以下是一个使用静态成员函数实现工厂模式的示例代码:
class Product {
public:
virtual ~Product() {}
};
class ProductA : public Product {
public:
ProductA() {}
};
class ProductB : public Product {
public:
ProductB() {}
};
class Factory {
public:
static Product* createProductA() {
return new ProductA();
}
static Product* createProductB() {
return new ProductB();
}
};
在上述代码中,我们定义了一个抽象基类Product和两个继承自Product的具体类ProductA和ProductB。在Factory类中,我们定义了两个静态成员函数createProductA和createProductB,用于创建并返回ProductA和ProductB的对象实例。
总结
本文介绍了C++中静态成员变量、静态常量和静态成员函数的特性、应用、常见的软件设计模式以及单例模式、工厂模式的实现。静态成员变量、静态常量和静态成员函数可以帮助我们更好地组织数据和操作,并提高代码的效率和可读性。
单例模式和工厂模式则是常用的软件设计模式,可以将对象的创建和使用解耦,降低系统的复杂度,并提高代码的可维护性和扩展性。
通过本文的学习,我们可以更好地应用C++中的静态成员变量、静态常量和静态成员函数,并了解常见的软件设计模式以及如何实现单例模式和工厂模式。