C++ 工厂方法
工厂方法是 C++ 中的一种对象创建设计模式,用于创建对象同时隐藏其组合,以便用户可以使用接口而无需看到任何方法调用。
C++ 中的工厂方法
工厂是虚拟构造函数,允许程序员设计让用户与干净的程序界面交互的程序。 这意味着将对象创建本身隐藏在父类中。
如果一个程序有两个类,一个父类和一个用户子类,使用构造函数会导致两个类高度依赖。 父类内部引起的任何变化都会导致子类的后续变化。
工厂的功能是能够在程序开始时声明对象,并提供添加新对象的能力,因为所有所需的更改都将在库类内部进行,而不是在其他任何地方进行。
C++ 中的简单构造函数类
代码:
#include <iostream>
using namespace std;
// LIBRARY/PARENT(Wire_Sizes) CLASS WITH Two_mm and Four_mm sub-classes
class Wire_Sizes {
public:
virtual void Diameter() = 0;
};
class Two_mm : public Wire_Sizes {
public:
void Diameter() {
cout << "This wire is 2mm in diameter" << endl;
}
};
class Four_mm : public Wire_Sizes {
public:
void Diameter() {
cout << "This wire is 4mm in diameter" << endl;
}
};
// CLIENT(User) CLASS
// One thing to note here is that object creation takes place inside the User class, which can affect the whole program if changes are to be made to the parent class - like adding a new category of wire diameter.
// In this client class, adding a new type will mean adding a new category to the existing if-else ladder.
class User {
public:
User(int type) {
// Client explicitly creates classes according to type
if (type == 1)
pDiameter = new Two_mm();
else if (type == 2)
pDiameter = new Four_mm();
else
pDiameter = NULL;
}
~User() {
if (pDiameter)
{
delete[] pDiameter;
pDiameter = NULL;
}
}
Wire_Sizes* getDiameter() {
return pDiameter;
}
private:
Wire_Sizes *pDiameter;
};
// MAIN FUNCTION
int main() {
User *pClient = new User(2);
Wire_Sizes * pDiameter = pClient->getDiameter();
pDiameter->Diameter();
return 0;
}
输出:
This wire is 4mm in diameter
Wire_Sizes 是库或具有两个子类 Two_mm 和 Four_mm 的父类,其中方法 Diameter() 被重载,并在调用该方法时返回打印语句。
在 User 类中,参数类型从 main() 函数获取传递的值,并创建与返回类型匹配的对象类。 ~User()(析构函数)销毁分配的资源并清除指针。
main() 函数创建对象 *pClient,同时将值 2 传递给它。 该值将传递给 User(client) 类,该类将创建类型 2 的对象,然后从 Wire_Sizes(parent) 类调用类型 2 的相应方法。
这使得程序高度依赖于其子类并且使得代码密集。 工厂就是用来解决这个问题的。
在 C++ 的构造函数类中使用工厂方法
代码:
#include <iostream>
using namespace std;
// The three derived classes, Size_two_mm, Size_three_mm, and Size_four_mm, contains the
// printDiameter() method, which is overloaded in all the subclasses
enum Size {
Size_two_mm, Size_three_mm, Size_four_mm
};
class Wire_Sizes {
public:
virtual void printDiameter() = 0;
static Wire_Sizes* Create(Size type);
};
class Twomm : public Wire_Sizes {
public:
void printDiameter() {
cout << "This wire is 2mm in diameter" << endl;
}
};
class Threemm : public Wire_Sizes {
public:
void printDiameter() {
cout << "This wire is 3mm in diameter" << endl;
}
};
class Fourmm : public Wire_Sizes {
public:
void printDiameter() {
cout << "This wire is 4mm in diameter" << endl;
}
};
Wire_Sizes* Wire_Sizes::Create(Size type) {
if (type == Size_two_mm)
return new Twomm();
else if (type == Size_three_mm)
return new Threemm();
else if (type == Size_four_mm)
return new Fourmm();
else return NULL;
}
class user {
public:
user()
{
Size type = Size_three_mm;
pDiameter = Wire_Sizes::Create(type);
}
~user() {
if (pDiameter) {
delete[] pDiameter;
pDiameter = NULL;
}
}
Wire_Sizes* getDiameter() {
return pDiameter;
}
private:
Wire_Sizes *pDiameter;
};
int main() {
user *pClient = new user();
Wire_Sizes * pDiameter = pClient->getDiameter();
pDiameter->printDiameter();
return 0;
}
输出:
This wire is 3mm in diameter
在 Size 枚举数据中,首先键入程序中使用的三个对象。
if-else 条件写在 Wire_Sizes(library)
类之后的新构造函数 Create()
内。 添加新对象比更改客户端类更容易。
构造函数使用参数类型接收一个值,并在 if-else 梯形图中匹配它。 正匹配时调用相应的函数,负匹配时返回NULL。
用户类不会显式创建对象,而是将类型传递给工厂方法 Create()
。 对象 Size_ Three_mm 被传递给 type ,并且构造函数类 Create() 使用赋值运算符被分配给 pDiameter 。
~user()
(析构函数)销毁在类末尾分配的资源,并将 NULL 分配给变量 pDiameter。 在构造函数 getDiameter 内,返回变量 pDiameter。
main() 方法创建用户类的对象 *pClient
,该对象称为 pDiameter()
方法。 getDiameter()
方法返回 pDiameter 变量,该变量的值存储在类型内。
语法 Wire_Sizes * pDiameter = pClient->getDiameter();
将 getDiameter() 方法的值传递给存储 NULL 的 pDiameter,并调用 printDiameter()
方法。
C++ 中的具体类和抽象工厂方法
当声明一个方法或类时,它被称为抽象类,因为它无法返回某些内容;当定义该方法或类时,它被称为具体类。 具体类可以根据工厂内的要求进行实例化和调用。
代码:
#include <iostream>
using namespace std;
// BASE CLASS
class Concrete_Example {
public:
virtual ~Concrete_Example() {}
virtual std::string Operation() const = 0;
};
class ExampleProduct1 : public Concrete_Example {
public:
std::string Operation() const override {
return "{Product 1 is instantiated}";
}
};
class ExampleProduct2 : public Concrete_Example {
public:
std::string Operation() const override {
return "{Product 2 is instantiated}";
}
};
//CREATOR CLASS
class Create {
public:
virtual ~Create(){};
virtual Concrete_Example* FactoryMethod() const = 0;
std::string SomeOperation() const {
Concrete_Example* concrete_Example = this->FactoryMethod();
std::string result = "Client Code" + concrete_Example->Operation();
delete concrete_Example;
return result;
}
};
class ExampleCreator1 : public Create {
public:
Concrete_Example* FactoryMethod() const override {
return new ExampleProduct1();
}
};
class ExampleCreator2 : public Create {
public:
Concrete_Example* FactoryMethod() const override {
return new ExampleProduct2();
}
};
// USER CLASS
void User(const Create& create) {
std::cout << "User Method is called\n"
<< create.SomeOperation() << std::endl;
}
// MAIN FUNCTION
int main() {
std::cout << "App: Launched with the ConcreteCreator1.\n";
Create* create = new ExampleCreator1();
User(*create);
std::cout << std::endl;
std::cout << "App: Launched with the ConcreteCreator2.\n";
Create* create2 = new ExampleCreator2();
User(*create2);
delete create;
delete create2;
return 0;
}
输出:
App: Launched with the ConcreteCreator1.
User Method is called
Client Code{Product 1 is instantiated}
App: Launched with the ConcreteCreator2.
User Method is called
Client Code{Product 2 is instantiated}
在此示例中,将在工厂类中创建两个具体类,并将观察工厂如何调用类。 Concrete_Example(base) 类为产品及其接口提供了许多实现。
Concrete_Example 类有两个子类——ExampleProduct1 和ExampleProduct2,其中包含用户类想要调用的产品。 下面是 Create(creator)
类的具体实现 - 声明工厂方法会将一个对象从产品类传递到用户类。
创建子类是为了返回对象并实现用于该目的的方法。 虽然创建了类名,但在该类或其子类中并没有创建新对象。
Create 类的主要目的是从工厂方法返回产品。 子类可以重写该方法并向产品添加新的实现。
在 SomeOperation 方法内部,会创建工厂 Concrete_Example 方法中的一个对象,该对象用于实现对产品的更改。 可以看出,子类通过重写工厂方法对产品造成更改。
这里使用的客户端代码使用类创建实例及其子类来调用方法,使其独立于创建对象。 在设置或环境之后,应用程序选择创建者类型。
main函数使用classCreate形成子类ExampleCreator1()的对象。 在此程序中,这两个创建者方法都是使用从 Create 类创建的对象来调用的,并且在实现后,所有创建的对象都将被销毁。
相关文章
用 C++ 读取 PPM 文件
发布时间:2023/08/24 浏览次数:108 分类:C++
-
在本文中,我们将了解 PPM 文件并使用 C++ 读取它们。我们将首先讨论并了解 PPM 文件格式。 稍后,我们将学习用 C++ 读取 PPM 文件的分步过程。
检查 Linux 中的 C++ 编译器版本
发布时间:2023/08/24 浏览次数:60 分类:C++
-
本文是关于检查 Linux 操作系统上安装的 C++ 编译器的版本。 此外,在撰写本文时,我们还将探讨 C++ 最新版本 C++ 11 的激活过程。检查 Linux 中的 C++ 编译器版本
C++ 中结构体和类的区别
发布时间:2023/08/23 浏览次数:52 分类:C++
-
本文解释了 C++ 中结构体和类之间的区别。 本文是针对最新版本的 C++ 编写的; 旧版本中的结构和类之间存在更多限制和差异。在大多数情况下,结构与类非常相似,但差异很少。 让我们一一
C++ 中的类模板继承
发布时间:2023/08/23 浏览次数:142 分类:C++
-
本文将讨论 C++ 中最流行和最常用的方法之一(即类模板)。C++ 中模板的添加带来了一种新的编码范式,称为通用编程。 现在,这是 C++ 程序员工具包的一个重要元素,是许多标准库的基础,也
C++ 中的Point 和 Line 类
发布时间:2023/08/23 浏览次数:158 分类:C++
-
C++ 中的 Point 和 Line 类是可以表示点和线的主要数据类型。 它提供了操作点、条形和向量的方法。C++ 中 Point 和 Line 类的基本用例 Point 和 Line 类是 C++ 语言的基本部分。
在 C++ 中获取类名
发布时间:2023/08/23 浏览次数:100 分类:C++
-
在本文中,我们将学习如何使用 C++ 编程语言获取类名。C++ 类概述 在 C++ 中,一切都与类和对象相关,每个类和对象都有其特征和过程。
在 C++ 类中初始化静态变量
发布时间:2023/08/23 浏览次数:52 分类:C++
-
我们将在这篇短文中学习如何在 C++ 中初始化静态变量。在 C++ 中初始化静态变量 C++类中静态变量的初始化就是给静态变量赋值的过程。