在c++ 20下使用微软的proxy库替代传统的virtual动态多态

传统的virtual动态多态,经常会有下面这样的使用需求:

cpp 复制代码
#include <iostream>
#include <vector>

// 声明一个包含virtual虚函数的基类
struct shape
{
	virtual ~shape() {}

	virtual void draw() = 0;
};

// 派生,实现virtual虚函数
struct rectangle : shape
{
	virtual void draw() override
	{
		std::cout << "rectangle" << std::endl;
	}
};

// 派生,实现virtual虚函数
struct circle : shape
{
	virtual void draw() override
	{
		std::cout << "circle" << std::endl;
	}
};

int main()
{
	// 由于要用vector容器来保存各种不同的对象,所以这里容器元素的类型只能使用基类指针
	std::vector<shape*> vec;

	vec.emplace_back(new rectangle());
	vec.emplace_back(new circle());

	// 通过virtual动态多态调用,来实现调用真正的对象类型的成员函数
	for (const auto& p : vec)
	{
		p->draw();
	}

	// 输出:
	// rectangle
	// circle
}

上面同样的需求,换成proxy库来实现是这样的:

cpp 复制代码
#include <iostream>
#include <vector>
#include "proxy.h"

// 声明一个代理类,最终会通过这个代理类去调用真正的类对象的成员函数
struct draw : pro::dispatch<void()>
{
	template <class T>
	void operator()(T& self) { self.draw(); }
};

struct shape : pro::facade<draw> {};

// 不需要派生,不需要virtual虚函数
struct rectangle
{
    void draw()
    {
        std::cout << "rectangle"<< std::endl;
    }
};

// 不需要派生,不需要virtual虚函数
struct circle
{
    void draw()
    {
        std::cout << "circle" << std::endl;
    }
};

int main()
{
    // 这里容器元素的类型是个proxy的代理类型
    std::vector<pro::proxy<shape>> shapes;

	shapes.emplace_back(pro::make_proxy<shape>(rectangle()));
	shapes.emplace_back(pro::make_proxy<shape>(circle()));

    // 注意这里的调用方式和virtual动态多态的调用方式不同
    for (auto& p : shapes)
    {
        p.invoke<draw>();
    }

    // 输出:
    // rectangle
    // circle
}

可以看到,换成proxy库之后,不再有virtual虚函数,而且是非侵入式的,我觉得这种方式非常棒,很优雅。至于性能测试,我没有去做。

详情见这个开源仓库地址:https://github.com/microsoft/proxy

最后编辑于:2023-08-24
相关推荐
一拳一个呆瓜1 天前
【MFC】对话框属性:Absolute Align(绝对对齐)
c++·mfc
爱编程的化学家1 天前
代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和
数据结构·c++·算法·leetcode·双指针·哈希
许怀楠1 天前
【主页介绍】
linux·c++·贪心算法·visual studio
木心爱编程1 天前
C++链表实战:STL与手动实现详解
开发语言·c++·链表
离越词1 天前
QTday1作业
c++·qt
HAH-HAH1 天前
【蓝桥杯 2024 国 Java A】粉刷匠小蓝
c++·学习·数学·算法·职场和发展·蓝桥杯·组合数学
小吴同学·1 天前
OPC Client第10讲:实现主界面;获取初始界面传来的所有配置信息config【C++读写Excel:xlnx;ODBC;缓冲区】
c++·wxwidgets
边疆.1 天前
【C++】继承详解
开发语言·c++·继承
hweiyu001 天前
C++设计模式,高级开发,算法原理实战,系统设计与实战(视频教程)
c++·算法·设计模式
十年编程老舅1 天前
‌C++左值与右值:从基础概念到核心应用‌
linux·c++·右值引用·c++17·c++左值·c++右值·左值引用