在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
相关推荐
tod11317 小时前
从零手写一个面试级 C++ vector:内存模型、拷贝语义与扩容策略全解析
c++·面试·职场和发展·stl·vector
OopspoO17 小时前
C++杂记——构造函数
c++
淦。。。。17 小时前
题解:P14013 [POCamp 2023] 送钱 / The Generous Traveler
开发语言·c++·经验分享·学习·其他·娱乐·新浪微博
天赐学c语言17 小时前
1.18 - 滑动窗口最大值 && 子类的指针转换为父类的指针,指针的值是否会改变
数据结构·c++·算法·leecode
是娇娇公主~18 小时前
C++集群聊天服务器(3)—— 项目数据库以及表的设计
服务器·数据库·c++
zephyr0518 小时前
C++ STL unordered_set 与 unordered_map 完全指南
开发语言·数据结构·c++
大锦终18 小时前
dfs解决FloodFill 算法
c++·算法·深度优先
一只小bit18 小时前
Qt 事件:覆盖介绍、处理、各种类型及运用全详解
前端·c++·qt·cpp
追烽少年x19 小时前
第三章 异常(一)
c++
苦藤新鸡19 小时前
14.合并区间(1,3)(2,5)=(1,5)
c++·算法·leetcode·动态规划