一、知识点总回顾(移动语义 + 智能指针)
核心知识点
-
移动语义
- 作用:转移对象资源所有权,避免低效深拷贝,提升性能
- 触发方式:
std::move()将对象转为右值引用 - 核心函数:移动构造函数
类名(类名&&)、移动赋值重载返回值 operator=(类名&&) - 编译器默认生成函数:无参构造、拷贝构造、移动构造、拷贝赋值、移动赋值、析构函数
-
智能指针(RAII 资源管理)
- 核心思想:利用类生命周期自动管理堆裸指针,构造获取资源,析构释放资源,防止内存泄漏
- 自定义智能指针必备接口:构造函数、析构函数、
operator->(指针访问)、operator*(解引用)、get()(获取原生指针)、reset()(手动释放资源) - C++11 标准智能指针
unique_ptr:独占式智能指针,同一资源仅能被一个指针管理shared_ptr:共享式智能指针,内部引用计数,多指针共管同一资源weak_ptr:弱引用指针,不增加引用计数 ,专门解决shared_ptr循环引用问题,必须依托shared_ptr使用
对应代码
cpp
//综合应用
/*
*回顾知识点:
* 1.移动语义; 将某一个对象的数据转移到另一个对象中,避免不必要的拷贝,
* 1) std::move()触发
* 2)移动构造函数:类名(类名&&)
* 3)移动赋值重载; 返回类型 operator=(类名&&)
*
* 一个类编译器默认提供无参构造,拷贝构造,移动构造,拷贝赋值,移动赋值,析构函数
*
* 2.智能指针 : 依据类的生命周期(构造函数,析构函数)去自动管理原生指针,也叫做裸指针
* 1)自定义智能指针:
* 构造函数(数据类型 *):RAII(资源获取即初始化)
* 析构函数: 回收原始的指针
* operator -> () 指针访问
* operator*(): 指针解引用
* 数据类型 * get(): 获取原始指针,返回原始指针,但原始指针的生命周期仍然受智能指针控制。使用 get() 时需要小心,避免与智能指针的自动管理机制冲突。
* void reset():手动释放原始指针
*
* 2)C加加11提供的智能指针: 类模板
* auto_ptr<数据类型>:放弃
* unique_ptr<数据类型>:独占
* shared_ptr<数据类型>:共享
* weak_ptr<数据类型>:弱引用
* 必须指向shared_ptr,但是不增加引用计数
* 用于解决shared_ptr 的循环引用问题
*/
二、设计模式基础介绍
核心知识点
- 设计模式:共 23 种经典设计模式,用于规范类与代码结构,简化设计、提升代码扩展性、可维护性。
- 三大分类:创建型模式、结构型模式、行为型模式。
对应代码
cpp
//1.设计模式: 类的设计模式 (23种),分三大类型(创建类型,结构类型,行为类型)
//简化类的设计,提高程序的扩展性等
三、单例设计模式
核心知识点
- 单例模式 :整个程序生命周期内,类有且仅有一个实例对象。
- 两大实现方式
- 懒汉式:第一次使用对象时才创建实例,延迟加载。
- 饿汉式:程序启动、类加载时就提前创建实例,无论是否使用。
- 单例实现步骤
- 私有化构造函数,禁止外部创建对象;
- 删除拷贝构造、移动构造、拷贝赋值,禁止克隆对象;
- 提供
public静态成员函数,对外获取唯一实例; - 饿汉式:定义静态类对象作为唯一实例;懒汉式:在静态函数内定义局部静态对象。
对应代码
cpp
//2.单例设计模式: 要求类的对象,在整体程序的生命周期内,只能创建一个类的对象。
// 按创建类对象的时机或位置,分为两个单例模式:
//1)懒汉式:第一次使用对象时,才创建对象,使用的时候才会创建
//2)饿汉式:程序启动时,就创建对象,类定义即创建我们的实例对象,无论是否使用,都会提前创建好
#if 0
#include<iostream>
using namespace std;
//定义web服务器: 之创建一个类的对象
//单例设计过程: 1)私有化构造函数 2)删除拷贝构造和移动构造(整个程序只能有一个,那么你就不能被克隆或者克隆)
//3)提供一个public静态函数,返回一个类的对象
//4)懒汉式;静态成员函数种去创建成员对象
//5)饿汉式:定义静态成员 类对象,在静态成员函数种返回这个类的对象
class WebServer {
int port;
string root;//web资源文件的跟目录
WebServer(int port = 443, string root = "/webroot") :port(port), root(root) {
}
WebServer(const WebServer&) = delete;
WebServer& operator=(const WebServer&) = delete;
WebServer(WebServer&&) = delete;//删除移动构造
public:
void start() {
cout << "Webserver Running localhost" << port << endl;
}
void shutdown() {
cout << "WebServer Stop" << endl;
}
//静态的成员函数的参数表尽量同构造函数的参数表相同
static WebServer& getInstance(int port, string root) {
//懒汉式
//static WebServer server(port, root);//局部的static 对象,在程序运行期间,只会定义一次
//return sever;
return intance;
}
//饿汉模式
static WebServer intance;//只是声明
};
void runServer() {
WebServer::getInstance(8080, "/webroot").start();
}
void stopServer() {
WebServer::getInstance(8080, "/webroot").shutdown();
}
WebServer WebServer::intance(8080);//定义
int main() {
WebServer::getInstance(8080,"/webroot").start();
}
#endif
四、工厂设计模式
4.1 模式分类 & 核心知识点
- 简单工厂
- 特点:一个工厂类生产所有产品,产品类型固定,新增产品需要修改工厂代码,违反开闭原则。
- 开闭原则:对扩展开放,对原有代码修改关闭。
- 工厂方法
- 特点:一个工厂只负责生产一种产品,不同产品对应专属工厂,遵循开闭原则。
- 抽象工厂
- 特点:一个工厂可以生产同系列 / 多类组合产品(如手机、平板、电脑),解决工厂方法单一产品的局限性。
- 通用结构:抽象产品接口 → 具体产品类 → 抽象工厂接口 → 具体工厂类。
4.2 对应代码
cpp
#if 0
#include<iostream>
using namespace std;
//3.工厂设计模式:思考铲平如何通过工厂生产出来的
//简单工厂:工厂只需要用户一共产品类型,即可以生产出来,生产的东西只能是固定的,不能生产它没有的,违反了开闭原则。
// 开闭原则:在不该现有代码的基础上,对扩展开放,对修改关闭
//工厂方法:不同的产品可以由不同的工厂生产出来,例如:苹果手机由苹果工厂生产(只能生产手机),小米手机由小米工厂生产
//前两种都是一个工厂只能生产一种产品,
//抽象工厂; 不同的工厂可以生成相同类型或组合的产品,即一个工厂可以生产多个不同类型的产品例如:苹果工厂可以生产苹果手机,苹果电脑等
//解决工厂方法的单一性,抽象工厂可以生产组合或套装产品(或同系列)
//产品类: 抽象类或者接口
// 产品类: 抽象类或接口
class IPhone {
public:
// 产品的功能
virtual void tell(string num) = 0;
};
// 定义具体的产品: 某一种类型
class HWPhone : public IPhone {
public:
void tell(string num) {
cout << "HWPhone tell: " << num << endl;
}
};
class VivoPhone : public IPhone {
public:
void tell(string num) {
cout << "VivoPhone tell: " << num << endl;
}
};
class MIPhone : public IPhone {
public:
void tell(string num) {
cout << "MIPhone tell: " << num << endl;
}
};
// 简单工厂: 产品类型固定, 定义好之后无法扩展
class PhoneFactory {
public:
enum Type
{
HW,
VIVO,
MI
};
// 依据用户的提供产品类型 来生产
static shared_ptr<IPhone> create(Type type = HW) {
switch (type) {
case HW: return shared_ptr<IPhone>(new HWPhone());
case VIVO: return shared_ptr<IPhone>(new VivoPhone());
default: return shared_ptr<IPhone>(new MIPhone());
}
}
};
#if 0
int main() {
shared_ptr<IPhone> phone = PhoneFactory::create();
phone->tell("110");
shared_ptr<IPhone> phone2 = PhoneFactory::create(PhoneFactory::VIVO);
phone2->tell("120");
return 0;
}
#endif
//工厂方法设计模式: 每一个工厂只负责一个产品的生产
class IFactory {
public:
virtual shared_ptr<IPhone> create()=0;
};
class HWFactory : public IFactory {
public:
shared_ptr<IPhone> create() {
return shared_ptr<IPhone>(new HWPhone());
}
shared_ptr<IPhone> create2() {
return shared_ptr<IPhone>(new VivoPhone());
}
shared_ptr<IPhone> create3() {
return shared_ptr<IPhone>(new MIPhone());
}
};
#if 0
int main() {
//需要HWPhone,只需要通过它的工厂生产即可。
shared_ptr<IPhone> phone = HWFactory().create();
phone->tell("110");
return 0;
}
#endif
#if 1
//抽象工厂,工厂可以生产同类型或品牌的系列产品
class IPad {
public:
virtual void playGame() = 0;
};
class IComputer {//电脑产品接口
public:
virtual void softDev() = 0;
};
class HWPad :public IPad {
public:
void playGame() {
cout << "HWPad playGame()" << endl;
}
};
class XMPad :public IPad {
public:
void playGame() {
cout << "XMPad playGame()" << endl;
}
};
class VIvoPad :public IPad {
public:
void playGame() {
cout << "VIvoPad playGame()" << endl;
}
};
class HWComputer :public IComputer {
public:
void softDev() {
cout << "HW" << endl;
}
};
class XMComputer :public IComputer {
public:
void softDev() {
cout << "XM" << endl;
}
};
class VIvoComputer:public IComputer {
public:
void softDev() {
cout << "VIvo" << endl;
}
};
//抽象工厂的接口类
class IFactory {
public:
virtual shared_ptr<IPhone> createPhone() = 0;
virtual shared_ptr<IPad> createPad() = 0;
virtual shared_ptr<IComputer> createComputer() = 0;
};
class HWFactory : public IFactory {
public:
shared_ptr<IPhone> createPhone() {
return shared_ptr<IPhone>(new HWPhone());
}
shared_ptr<IPad> createPad() {
return shared_ptr<IPad>(new HWPad());
}
shared_ptr<IComputer> createComputer() {
return shared_ptr<IComputer>(new HWComputer());
}
};
class XMFactory : public IFactory {
public:
shared_ptr<IPhone> createPhone() {
return shared_ptr<IPhone>(new MIPhone());
}
shared_ptr<IPad> createPad() {
return shared_ptr<IPad>(new XMPad());
}
shared_ptr<IComputer> createComputer() {
return shared_ptr<IComputer>(new XMComputer());
}
};
class VIvoFactory : public IFactory {
public:
shared_ptr<IPhone> createPhone() {
return shared_ptr<IPhone>(new VivoPhone());
}
shared_ptr<IPad> createPad() {
return shared_ptr<IPad>(new VIvoPad());
}
shared_ptr<IComputer> createComputer() {
return shared_ptr<IComputer>(new VIvoComputer());
}
};
#endif
#endif
五、观察者模式
核心知识点
- 观察者模式 :俗称发布 - 订阅模式,属于行为型设计模式。
- 两大核心角色
- 主题(发布者):维护核心数据、观察者列表;提供注册 / 注销观察者、数据更新、批量通知接口。
- 观察者(订阅者):实现统一更新接口,接收主题推送的消息并响应。
- 运行逻辑:主题数据发生变化 → 主动通知所有已注册观察者 → 观察者执行自身更新逻辑。
对应代码
cpp
#if 0
#include<iostream>
#include<vector>
using namespace std;
//4.观察者模式:简化版的发布与订阅模式
// 组成: 主题,观察者
// 主题:核心数据(天气,GPS位置,网络时间)
// 要求必须有
//添加或删除观察者,更新数据函数,通知接口
//观察者: 必须存在 接收主题通知的函数 (如 update )
//被动性的,当我们关注的主题数据发生变化时,会被主题通知,然后执行自己的更新函数
//设计主题类
// 设计观察者接口类
class INTObserver {
public:
virtual void update(string timeStr) = 0;
};
// 设计主题类
class NetworkTimerServer {
string current_time; // 数据
vector<shared_ptr<INTObserver>> allOb; // 所有注册的观察者
public:
NetworkTimerServer() :current_time("") {}
// 注册观察者
void regist(shared_ptr<INTObserver> ob) {
allOb.push_back(ob);
}
// 取消注册观察者
void unregist(shared_ptr<INTObserver> ob) {
auto it = allOb.begin();
while (it != allOb.end()) {
if (it->get() == ob.get()) {
allOb.erase(it);
break;
}
}
}
void setCurrentTime(const string& timeStr) {
this->current_time = timeStr;
notify();
}
string getCurrentTime() {
return this->current_time;
}
void notify() {
// 通知所有观察者数据发生了变化
for (auto ob : allOb) {
ob->update(current_time);
}
}
};
// 设计具体的观察者
class PhoneObserver : public INTObserver {
public:
void update(string timeStr) override {
cout << "PhoneObserver Current Time: " << timeStr << endl;
}
};
class PadObserver : public INTObserver {
public:
void update(string timeStr) override {
cout << "PadObserver Current Time: " << timeStr << endl;
}
};
class WatchObserver : public INTObserver {
int i;
public:
WatchObserver() :i(0) {}
void update(string timeStr) override {
if (i % 4 == 0)
cout << "WatchObserver Current Time: " << timeStr << endl;
i++;
}
};
#include <thread>
#include <iomanip>
#include <chrono>
#include <sstream>
int main() {
// register int i = 0; // 建议变量存储在寄存器中
unique_ptr<NetworkTimerServer> nts(new NetworkTimerServer());
shared_ptr<INTObserver> ob1 = shared_ptr<INTObserver>(new PhoneObserver());
shared_ptr<INTObserver> ob2 = shared_ptr<INTObserver>(new PadObserver());
shared_ptr<INTObserver> ob3 = shared_ptr<INTObserver>(new WatchObserver());
nts->regist(ob1);
nts->regist(ob2);
nts->regist(ob3);
// 模拟时钟
for (int i = 0; i < 10; i++) {
auto ct = chrono::system_clock::now();
time_t tt = chrono::system_clock::to_time_t(ct);
ostringstream oss;
oss << put_time(localtime(&tt), "%Y-%m-%d %H:%M:%S");
// 更新时间
nts->setCurrentTime(oss.str());
// 休息1s
this_thread::sleep_for(chrono::seconds(1));
}
return 0;
}
#endif
六、构建器模式(建造者模式)
核心知识点
- 构建器模式 :用于成员属性繁多、构造函数重载复杂的类,拆分对象创建步骤,实现流式构建。
- 实现步骤
- 私有化外部类构造函数,禁止外部直接实例化;
- 定义静态内部构建器类 Builder;
- Builder 中提供链式成员函数,逐个设置对象属性;
- 最终通过
build()方法生成并返回完整对象。
- 流式构建:成员函数返回构建器自身引用,支持连续调用。
对应原版代码
cpp
#if 0
#include <iostream>
using namespace std;
// 1. 构建器模式
// 将复杂性创建对象的类,设计为分层次的创建过程。
// 复杂性创建,如: 类的成员属性较多, 构造函数重载也非常多
// 构建器模式的设计过程: 【流式构建器】
// 1) 私有化构造函数, 隐藏类对象的创建过程
// 2) 在类内设计静态公开的成员类 (内部类) 为 构建器类 Builder
// 3) 在Builder 类内,设计公开的成员函数,提供属性的设计 为 构建过程(层次)
// 最后提供一个 build()函数返回 外部类的对象。
#include <memory>
class Computer {
string vendor; // 厂家
string cpuName; // 处理器名称
int cpuNum; // 内核数
int memorySize; // 内存大小
int ssdSize; // 硬盘大小
// ... 其他大量的属性
private:
Computer() :vendor("中国"), cpuName("Intel"), cpuNum(2), memorySize(4), ssdSize(40) {}
Computer(string vendor) :vendor(vendor), cpuName("Intel"), cpuNum(2), memorySize(4), ssdSize(40) {}
Computer(string vendor, string cpuName) :vendor(vendor), cpuName(cpuName), cpuNum(2), memorySize(4), ssdSize(40) {}
Computer(string vendor, string cpuName, int cpuNum)
:vendor(vendor), cpuName(cpuName),
cpuNum(cpuNum), memorySize(4), ssdSize(40) {
}
Computer(string vendor, string cpuName, int cpuNum, int memorySize)
:vendor(vendor), cpuName(cpuName),
cpuNum(cpuNum), memorySize(memorySize), ssdSize(40) {
}
Computer(string vendor, string cpuName, int cpuNum, int memorySize, int ssdSize)
:vendor(vendor), cpuName(cpuName),
cpuNum(cpuNum), memorySize(memorySize), ssdSize(ssdSize) {
}
public:
void show() {
cout << vendor << " 生产 " << cpuName << "(" << cpuNum << ") 内存 " << memorySize << "G";
cout << " ssd " << ssdSize << " G" << endl;
}
// 静态内部类: 可以访问外部类的私有成员
static class Builder {
shared_ptr<Computer> computer;
public:
Builder() {
computer = shared_ptr<Computer>(new Computer());
}
// 设计构建过程成员函数: 如果返回构建器类的引用 ,称之为 流式构建
Builder& vendor(string v) {
computer->vendor = v;
return *this;
}
Builder& cpuNum(int n) {
computer->cpuNum = n;
return *this;
}
Builder& memSize(int n) {
computer->memorySize = n;
return *this;
}
Builder& ssdSize(int n) {
computer->ssdSize = n;
return *this;
}
shared_ptr<Computer> build() {
return computer;
}
};
};
int main() {
shared_ptr<Computer> c = Computer::Builder()
.cpuNum(8).memSize(32).ssdSize(1024).build();
c->show();
return 0;
}
#endif
七、附加练习代码(图形类 + STL 算法练习)
7.1 图形面积计算(多态 + 智能指针)
知识点
- 抽象基类定义纯虚函数,实现多态;
- 使用
unique_ptr管理堆对象,自动释放资源。
代码
cpp
#if 0
#include<iostream>
#include<memory>
using namespace std;
#define pai 3.14
class Shape {
public:
virtual void alcArea() = 0;
};
class Circle :public Shape {
private:
double t;
double area;
public:
Circle(double r,double area = 0) :t(r),area(area){};
void alcArea() override {
area = pai * t * t;
cout<<"圆的面积是"<<area<<endl;
}
};
int main() {
unique_ptr<Shape> s(new Circle(5.0));
s.get()->alcArea();
}
#endif
7.2 vector + for_each + Lambda 练习
知识点
emplace_back原位构造元素,效率高于push_back;for_each遍历算法结合 Lambda 表达式处理容器元素。
代码
cpp
#if 0
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v;
v.emplace_back(1);
v.emplace_back(3);
v.emplace_back(5);
v.emplace_back(7);
v.emplace_back(9);
for (auto v : v) {
cout << v << endl;
}
for_each(v.begin(), v.end(), [](int v) {cout<<v*2<<endl; });
return 0;
}
#endif
全文总结
- 前置复习:移动语义优化拷贝效率,各类智能指针基于 RAII 实现内存自动管理。
- 单例模式:保证全局唯一实例,分懒汉、饿汉两种实现。
- 工厂模式:简单工厂(违反开闭)、工厂方法(一厂一物)、抽象工厂(一厂多系列产品)。
- 观察者模式:发布订阅模型,主题推送消息,观察者被动响应。
- 构建器模式:解决多参数复杂对象创建,支持流式调用。
- 附加练习巩固:C++ 多态、智能指针、STL 容器与算法综合使用。