1. 简单工厂模式
- 什么是简单工厂
简单工厂模式有一个工厂,可以生产多个产品,包含两个接口,一个是产品类的,一个是工厂类的。
产品类需要有一个基类,基类中的具体产品实现需要是个纯虚函数,这样一来,产品的子类必须要重写具体的产品实现,实现不同的功能。
产品类封装完成后,还需要一个工厂类,工厂类对产品类再次封装,最终实现由一个工厂对象决定创建出哪一种产品类的实例。
- 代码实例
//简单工厂模式
#include<iostream>
using namespace std;
#define message(arg) cout<<"The value of "#arg<<":"<<arg<<endl
enum operationTypeE {
ADD,
MUL
};
//产品的基类
class Product{
public:
//基类中的纯虚函数virtual int operation(int a, int b) = 0;
virtual int operation(int a, int b)
{
}
};
//产品的子类Add
class Product_Add : public Product{
public:
int operation(int a, int b){
return a + b;
}
};
//产品的子类Mul
class Product_Mul : public Product{
public:
int operation(int a, int b){
return a * b;
}
};
//工厂
class SimpleFactory{
public:
Product* Create(operationTypeE operationType){
switch (operationType) {
case ADD:
return new Product_Add;
break;
case MUL:
return new Product_Mul;
break;
default:
break;
}
}
};
int main()
{
SimpleFactory *factory = new SimpleFactory();
Product *productAdd = factory->Create(ADD);
Product *productMul = factory->Create(MUL);
int add_result = productAdd->operation(1, 2);
int mul_result = productMul->operation(1, 2);
message(add_result);
message(mul_result);
return 0;
}
2. 工厂方法模式
- 什么是工厂方法
为了满足开闭原则(扩展开放,修改关闭),将工厂抽象化,每一个产品对应一个工厂方法。这样在新增加一个产品时候,不需要更改工厂。
//简单工厂模式
#include<iostream>
using namespace std;
#define message(arg) cout<<"The value of "#arg<<":"<<arg<<endl
enum operationTypeE {
ADD,
MUL
};
//产品的基类
class Product{
public:
//基类中的纯虚函数virtual int operation(int a, int b) = 0;
virtual int operation(int a, int b)
{
}
};
//产品的子类Add
class Product_Add : public Product{
public:
int operation(int a, int b){
return a + b;
}
};
//产品的子类Mul
class Product_Mul : public Product{
public:
int operation(int a, int b){
return a * b;
}
};
//工厂
class AbstractFactory{
public:
virtual Product* create() = 0;
};
//实现工厂方法add
class FactoryAdd: public AbstractFactory {
public:
Product *create()
{
return new Product_Add();
}
};
//实现工厂方法multiply
class FactoryMul: public AbstractFactory {
public:
Product *create()
{
return new Product_Mul();
}
};
int main()
{
FactoryAdd *factoryAdd = new FactoryAdd;
FactoryMul *factoryMul = new FactoryMul();
Product *productAdd = factoryAdd->create();
Product *productMul = factoryMul->create();
int add_result = productAdd->operation(1, 2);
int mul_result = productMul->operation(1, 2);
message(add_result);
message(mul_result);
return 0;
}
3. 抽象工厂模式
-
什么是抽象工厂
当有不同类型的产品时,就需要用到抽象工厂,实现思路就是,在工厂接口内规范不同类型产品的接口,然后通过工厂方法分别去实现不同类型的产品。 -
因为抽象工厂,可以在工厂方法上进行扩展,这里就不详细举例了。
4. 单例设计模式
-
什么是单例模式
单例模式就是确保一个类只有一个实例。
保证单例模式的前提条件:
a. 私有构造函数
b. 静态引用变量
c. 返回静态引用的公共静态方法 -
单例模式的两种实现方式
a. 懒汉模式:延迟加载,什么时候用到,什么时候创建实例化对象。非线程安全。
b. 饿汉模式:类加载的时候就创建实例化对象。线程安全。 -
懒汉模式,代码实现
注意:静态成员变量,必须在类外初始化
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
#define message(arg) cout<<"the value of "#arg<<": "<<arg<<endl
#define nullptr NULL
//懒汉模式:私有静态引用和私有构造函数,在实例方法中实例化对象
class singletonClass
{
private:
//private reference
static singletonClass* getSingleton;
//constructor func
singletonClass(string name, uint16_t age)
{
cout << "start create the instance" << endl;
this->name = name;
this->age = age;
}
public:
//静态方法,通过类就可以访问
static singletonClass* getInstance()
{
if (getSingleton == nullptr)
{
getSingleton = new singletonClass("HandsomeBoy", 25);
}
return getSingleton;
}
void printAddress()
{
printf("The address of current singleton address = %p\n", getSingleton);
}
public:
string name;
uint16_t age;
};
//very important, it will prompt "undefined reference to `singleton::instance_'" if no below action
//静态成员变量必须在类外面初始化
singletonClass* singletonClass::getSingleton = nullptr;
int main()
{
cout << "First to create instance" << endl;
singletonClass* instance_1 = singletonClass::getInstance();
message(instance_1->age);
message(instance_1->name);
instance_1->printAddress();
printf("\n");
cout << "Second to create instance" << endl;
singletonClass* instance_2 = singletonClass::getInstance();
message(instance_2->age);
message(instance_2->name);
instance_2->printAddress();
return 0;
}
- 运行结果
First to create instance
start create the instance
the value of instance_1->age: 25
the value of instance_1->name: HandsomeBoy
The address of current singleton address = 00C879B0 ----> 两次实例化返回的是同一个对象地址。
Second to create instance
the value of instance_2->age: 25
the value of instance_2->name: HandsomeBoy
The address of current singleton address = 00C879B0 ----> 两次实例化返回的是同一个对象地址。
[Finished in 1.5s]
- 饿汉模式,代码实现
注意:需要使用局部静态变量,然后返回引用。
知识点:
函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,因为他的生命周期是整个程序运行周期。
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
#define message(arg) cout<<"the value of "#arg<<": "<<arg<<endl
#define nullptr NULL
//懒汉模式:私有静态引用和私有构造函数,在实例方法中实例化对象
class SingletonClass
{
private:
//constructor func
SingletonClass()
{
cout << "start create the instance" << endl;
}
SingletonClass(const SingletonClass& other); //显式的声明类拷贝
SingletonClass & operator = (const SingletonClass &); //重载操作符
public:
//静态方法,通过类就可以访问
static SingletonClass* getInstance()
{
static SingletonClass getSingleton;
//getSingleton = new SingletonClass(); //如果使用这种方式,则不是单例模式
return &getSingleton;
}
};
int main()
{
cout << "First to create instance" << endl;
SingletonClass* instance_1 = SingletonClass::getInstance();
printf("\n");
cout << "Second to create instance" << endl;
SingletonClass* instance_2 = SingletonClass::getInstance();
return 0;
}
- 运行结果
First to create instance
start create the instance //仅仅调用了一次构造函数
Second to create instance
[Finished in 0.9s]
5. 类模板
-
什么是类模板
顾名思义,就是定义一个类的模板,类模板的一个实例,就叫模板类。 -
简单示例
在复数运算规则中,实数和虚数是分别做运算的,所以可以定义一个类模板,重载+运算符,实现不管是int/float/double是任意数据类型,都可以做复数的加法运算。 -
代码实现
#include <cstdio>
#include <iostream>
using namespace std;
#define message(arg) cout << "The value of "#arg << " : "<< arg << endl
template <typename T>
class Complex{
public:
//构造函数
Complex(T real, T imaginary)
{
this->real = real;
this->imaginary = imaginary;
}
//运算符重载
Complex<T> operator+(Complex& other)
{
Complex<T> tmp(this->real + other.real, this->imaginary + other.imaginary);
return tmp;
}
public:
T real;
T imaginary;
};
int main()
{
//对象的定义,必须声明模板类型,因为要分配内容
Complex<int> length(10, 20);
Complex<int> width(20, 30);
Complex<int> high(30, 40);
Complex<int> result = length + width + high;
message(result.real);
message(result.imaginary);
return 0;
}
- 运算结果
The value of result.real : 60
The value of result.imaginary : 90
[Finished in 3.1s]