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

c++26新功能—indirect<T>和polymorphic<T>

一、indirect<T> 和 polymorphic<T>

indirect,间接的;polymorphic,多态。前者大家可能还有些生疏,但对后者应该是非常熟悉的。在C++26的模板支持中,提供了两个新类模板即indirect<T>和polymorphic<T>。主要目的是为了更完善的通过特化来实现具体的值语义。注意,是值语义。特别是后者,可以实现多态性质的值与其它标准库类型整体的组合,进而让编译器能够生成相关的函数和接口。
它们二者都是为动态分配对象的一种值语义控制的接口,其常量性都具有传染性。indirect<T>会持有T的对象并在复制indirect<T>时深拷贝T对象;polymorphic<T>有点类似于多态的控制,它持有一个T对象,但复制polymorphic<T>时会复制T的子类对象。
在C++的开发者中,处理多态一般是使用指针或引用。为了区别与指针等的不同,完善标准库中对值语义的相关内容,支持在复合类型中可以更简单方便的实现相关的代码。所以标准库中增加了对此二者的扩展。

二、具体的分析

在使用指针类型时,开发者可能会遇到一个问题,在pimpl中,如果一不小心会遇到非完全类型的的情况。也就是说,C++中提供了间接控制对象的指针类型。但在实际的开发过程中,其实也是需要对象的值类型的。特别是在存在继承的情况下,在标准库中的应用如果想控制值语义,需要通过一些技术方法才可能实现。
在C++26中完善了这方面的技术细节,通过indirect<T> 和 polymorphic<T>来达到相关的设计目的。特别是在复合类的设计中,其具有非常重要的意义 。正如上面据说,这两个类模板都具有常量传播和深拷贝的性质。除此之外,它们还具有一些特点:

  1. 无值状态
    为了支持实现移动语义的相关控制,它们都有一个无值状态。达种状态下,如果进行了移动操作,则可以通过成员函数valueless_after_move来判断是否正常
  2. 分配器支持
    二者均为分配器感知类型,所以其适合于此种类型的容器应用。如std::vector或std::map等
  3. 支持受限的契约扩展
    即支持在运行时的先决条件下的契约开发,但operator-> 和 operator*两个运算符除外
  4. 提供了完美转发运算符
    和optional和variant等一样,提供了完美转发的的相关运算符

需要提醒一下的是,要区别与indirect<T>和variant<Ts…>的不同,variant提供了多种可选类型之一的控制而indirect<T>则提供了单一类型的控制。而与智能指针相比,这两个类模板又提供了值语义和深拷贝且可以正确传播常量。
另外,polymorphic<T>需要派生类必须有公开的拷贝构造函数;其接口基类需要受保护的析构和拷贝构造函数。

三、应用场景

在标准的设计目的中,二者的应用主要有以下场景:

  1. 需要动态存储类型且类型已知的情况下,如上文提到的PIMPL、对象优化或减小头文件依赖等等
  2. 需要在运行时处理多种不同的子类并希望它们以值类型存储在同一容器中时,可以使用polymorphic<T>
  3. 一般是应用在复合类中

四、具体的例程

由于具体的标准尚未正式推出,所以看一下相关的提案中的例程:

struct A {enum class Constness { CONST, NON_CONST };Constness foo() { return Constness::NON_CONST; }Constness foo() const { return Constness::CONST; }
};class Composite {indirect<A> a_;Constness foo() { return a_->foo(); }Constness foo() const { return a_->foo(); }
};int main() {Composite c;assert(c.foo() == A::Constness::NON_CONST);const Composite& cc = c;assert(cc.foo() == A::Constness::CONST);
}// std::polymorphic
#include <memory>
#include <vector>
#include <iostream>class Shape {
public:virtual ~Shape() = default;virtual double area() const = 0;
};class Circle : public Shape {
private:double r_;
public:Circle(double radius) : r_(radius) {}double area() const override {return 3.14 * r_ * r_;}};class Rectangle : public Shape {
private:double w_, h_;
public:Rectangle(double width, double height) : w_(width), h_(height) {}double area() const override {return w_ * h_;}};int main() {std::vector<polymorphic<Shape>> vecShapes;vecShapes.push_back(Circle(3.0));vecShapes.push_back(Rectangle(2.2, 3.3));vecShapes.push_back(Circle(3.5));for (const auto& s : vecShapes) {s->area(); }return 0;
}

说明:代码仅供参考,无法保证可正常运行。

五、总结

在标准的学习中,一定要掌握其类似的库应用,比如本文介绍的两个类模板与variant的不同,二者与智能指针的不同,等等。重点是掌握它们的侧重点在哪里,它们如何能够互相完善C++中的各种场景的实现。就如同辨别孪生兄弟一样,只有掌握好细节的不同,才能更好的展开对技术的应用。

http://www.dtcms.com/a/462901.html

相关文章:

  • 网站建设方案文本模板网站服务器环境不支持mysql数据库
  • 网站建设费可以一次性冲费用吗手机免费建设网站制作
  • string的自主实现
  • usart波特率为9600和115200时,发送一句话所耗费的时间分别是多少
  • 灌南住房建设局网站网站建设收费标准不一
  • 前端学习手机网站开发吗黄金网站软件免费
  • 网站建设认知与理解营销平台建设
  • 免费创建属于自己的网站呼和浩特百度seo
  • k8s-pod部署java应用,jvm内存正常,但是pod内存不足oom排查
  • 公司网站建设合同需要交印花税中山专业网站建设模板代理
  • 网站开发需要解决难题项目网络图经常被称为
  • OSPF的高级特性
  • 安徽省建设工程造价管理网站wordpress嵌入php代码
  • 专门做网站的app怎样做网络推广优选豪升网络好
  • 网站空间150m跨境电商平台有哪些?列举5个
  • 怎么做网盘网站高培淇自己做的网站
  • spring ai mcp + 编写自动测试mcp服务端功能
  • 设备管理平台项目部署实验流程
  • 织梦网站文章发布信息模板下载去掉wordpress 上一篇
  • 有铁芯直线电机扰动力建模方法介绍
  • 图解 bulkProcessor(调度器 + bulkAsync() + Semaphore)
  • 监控系统3 - LVGL
  • 20-数组
  • 防水补漏东莞网站建设河北省建设厅办事大厅网站
  • logosc网站怎么做的减少wordpress响应时间
  • ps做的网站在线设计装修的网站
  • Python-UV环境管理实战
  • 江门建设建筑网站一个人做网站难吗
  • 网站开发使用哪些开发语言长沙的网站建设
  • 光效网站制作网站副本