当前位置: 首页 > news >正文

C++构造器设计模式

构造器模式可以简化复杂对象或一系列对象的构造过程,从而单独定义构成该复杂对象的各个组件的构建方法。

这篇文章只讲解较为简单的构造器的创建。创建一个构造器我们得了解如何实现流式调用以及如何关闭外界的访问权对构造函数的访问权限。

流式调用

所谓流式调用就是能实现在一行代码中连续调用多个函数的效果,具体效果如下:

Object obj;
obj.call("流").call("式").call("调").call("用");

而实现这种技术的方式很简单,就是让函数返回对象自身或者对象自身的指针,也就是*this或者this,具体实现如下:

class object {Object& call(string str) {// ...return *this;}
};

关闭构造函数访问权限

在构造器设计模式中,因为我们会提供专门的构造器供对象使用者创建对象,有时我们会不希望使用者跳过构造器直接使用构造函数构造,所以我们会选择将封闭构造函数。封闭构造函数的方式很简单,就是将构造函数设置为 protected 或者 private,如果你希望这个类未来可以被继承,那么就设置为 protected,否则可以设置为 private。由于对象封闭构造函数之后,构造器也无法创建该对象,我们需要给构造器一定的特权访问私有或保护的构造函数,我们需要将使用 friend class 构造器类设置为友元类。

构造器

假设我们存在下面的 Vec 类:

#include <string>
#include <vector>
#include <numeric>
#include <iostream>using namespace std;class Vec {vector<string> elements;
public:Vec& add_element(const string& element) {elements.emplace_back(element);return *this;}string str() {return accumulate(elements.begin(), elements.end(), string());}
};

这个类知识简单得封装了 elemnets 字符串容器对象,提供了流式调用填充容器的方法以及将容器对象转字符串的方法。我们会直接创建一个对象并使用它。

int main() {Vec vec;vec.add_element("流").add_element("式").add_element("调").add_element("用");cout << vec.str() << endl;
}

而使用构造器来创建会是怎样的呢?我们会在 Vec 类中提供一个静态方法 build 用于创建 Builder 类,然后将填充容器的工作交给 Builder 类,并在 Builder 类中提供转换函数,便于将 Builder 类隐式转换回为 Vec,那么我们的调用就会变成下面这样:

int main() {Vec vec = Vec::build().add_element("流").add_element("式").add_element("调").add_element("用");cout << vec.str() << endl;
}

这样看起来可能会有点造作,因为这个例子的构造比较简单并不能体现 Builder 的作用,但是简单的例子便于理解 Builder 的写法。下面我们具体介绍 Builder 的创建。

首先,我们需要修改 Vec 类,封闭构造函数的访问权限并提供静态方法用于构建 Builder:

class Vec {
public:vector<string> elements;// 静态方法返回 Builderstatic Builder& build();string str() {return accumulate(elements.begin(), elements.end(), string());}
protected:Vec() = default;// 友元 Builderfriend class Builder;
};//class Builder {
// ...
//}Builder& Vec::build() {Builder* builder = new Builder();return *builder;
}

然后是 Builder 类的构建:

class Builder {
public:Vec vec;// 转换函数operator Vec() const {return vec;}// 填充容器Builder& add_element(const string& element) {vec.elements.emplace_back(element);return *this;}
};

上面 Builder 类首先创建 Vec 类对象,然后提供 add_element 供用户填充 Vec 容器,最后使用 operator Vec() 将 Builder 隐式转换回 Vec 对象。

以上就是简单构造器模式的全部的实现了。

如果想要了解更复杂的构造器如何实现,可以查看 GitHub 仓库 GnCDesignPattern 的代码

相关文章:

  • 后端大量数据返回,采用数据压缩+分片操作,加快前端响应速度,个人技术总结
  • Nginx介绍
  • opencv进阶 ——(十三)基于三角剖分实现换脸
  • Unity【入门】重要组件和API
  • AIGC的算力与云边协同及应用创新
  • 笔记 | 软件工程04:软件项目管理
  • 收银系统源码-千呼新零售2.0【合作案例】
  • 【Spring Cloud】Feign详细介绍及底层原理解析
  • 深度学习_02_卷积神经网络循环神经网络
  • 【加密与解密】【01】网络安全体系
  • 修改west扩展命令的路径
  • Unity DOTS技术(二)ECS
  • Nginx通过转发代理解决跨域问题
  • Matlab 2024a 建模基础知识全面指南
  • ArrayList——简单洗牌算法
  • 2017-09-12 前端日报
  • 2017年终总结、随想
  • AHK 中 = 和 == 等比较运算符的用法
  • CAP理论的例子讲解
  • CSS实用技巧
  • HTTP--网络协议分层,http历史(二)
  • in typeof instanceof ===这些运算符有什么作用
  • Java 内存分配及垃圾回收机制初探
  • JavaScript DOM 10 - 滚动
  • JavaScript的使用你知道几种?(上)
  • JavaScript异步流程控制的前世今生
  • Java到底能干嘛?
  • java取消线程实例
  • JAVA之继承和多态
  • laravel 用artisan创建自己的模板
  • Vue小说阅读器(仿追书神器)
  • 聚类分析——Kmeans
  • 理解在java “”i=i++;”所发生的事情
  • 配置 PM2 实现代码自动发布
  • 前端攻城师
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 终端用户监控:真实用户监控还是模拟监控?
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • $(selector).each()和$.each()的区别
  • (1)svelte 教程:hello world
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (六)c52学习之旅-独立按键
  • (三)终结任务
  • (已解决)什么是vue导航守卫
  • (译) 函数式 JS #1:简介
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转)树状数组
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .NET NPOI导出Excel详解
  • .NET 表达式计算:Expression Evaluator
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .NET上SQLite的连接