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

news/2024/7/3 12:25:02 标签: c++20, virtual, 多态, 动态多态, c++

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

#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库来实现是这样的:

#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

http://www.niftyadmin.cn/n/4966560.html

相关文章

68、使用aws官方的demo和配置aws服务,进行视频流上传播放

基本思想&#xff1a;参考官方视频&#xff0c;进行了配置aws&#xff0c;测试了视频推流&#xff0c;rtsp和mp4格式的视频貌似有问题&#xff0c;待调研和解决 第一步&#xff1a;1) 进入aws的网站&#xff0c;然后进入ioT Core 2)先配置 Thing types & Thing&#xff0c…

数据结构基础:P3-树(上)----编程作业01:List Leaves

本系列文章为浙江大学陈越、何钦铭数据结构学习笔记&#xff0c;系列文章链接如下&#xff1a; 数据结构(陈越、何钦铭)学习笔记 文章目录 一、题目描述二、整体思路与实现代码 一、题目描述 题目描述&#xff1a; 给定一棵树&#xff0c;按照从上到下、从左到右的顺序列出所有…

Elasticsearch学习3-RestClient

1、RestClient 介绍 JavaREST客户端有两种模式&#xff1a; Java Low Level REST Client&#xff1a;ES官方的低级客户端。低级别的客户端通过http与Elasticearch集群通信。 Java High Level REST Client&#xff1a;ES官方的高级客户端。基于上面的低级客户端&#xff0c;也…

低代码赋能| 智慧园区项目开发痛点及解决方案

智慧园区是一个综合体&#xff0c;集技术开发、产业发展和学术研究于一体。作为未来智慧城市建设的核心&#xff0c;智慧园区充当着“产业大脑”和“指挥中心”的角色。它通过整合园区内的制造资源和第三方服务能力&#xff0c;实现园区各组成部分的协调运作、良性循环和相互促…

Flink流批一体计算(15):PyFlink Tabel API之SQL写入Sink

目录 举个例子 写入Sink的各种情况 1. 将结果数据收集到客户端 2. 将结果数据转换为Pandas DataFrame&#xff0c;并收集到客户端 3. 将结果写入到一张 Sink 表中 4. 将结果写入多张 Sink 表中 举个例子 将计算结果写入给 sink 表 #将Table API结果表数据写入sink表&…

C++11特性详解

一、简介 在C11标准出来之前&#xff0c;一直是C98/03标准占引领地位&#xff0c;而C98/03标准是C98标准在2003年将存在的一些漏洞进行了修复&#xff0c;但并没有核心语法的改动。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140个新特性&…

数据采集:selenium 获取某网站CDN 商家排名信息

写在前面 工作中遇到&#xff0c;简单整理理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式&#xff0c;是对大…

分布式系统与微服务的区别是什么?

分布式系统和微服务是两个相关但不同的概念&#xff0c;它们都是在构建复杂的软件应用时使用的架构思想。 分布式系统&#xff1a; 分布式系统是指由多个独立的计算机或服务器通过网络连接共同工作&#xff0c;协同完成一个任务或提供一个服务。在分布式系统中&#xff0c;各个…