运用成员函数模板接受所有兼容类型——条款45

《备考系统分析师》 - 专栏介绍和目录 本专栏提供软考高级系统分析师全套备考资料,包含四大核心内容:1.详细考点梳理(覆盖基础知识、关键技术、案例实践三大模块16个章节);2.历年真题及解析(2009-2022年所有真题含综合知识、案例分析和论文);3.100+篇高质量论文范文;4.预测模拟题。早鸟价仅需9.9元,可节约80%资料搜集时间,帮助考生高效备考、顺利通过考试。专栏持续更新,有问题可随时联系作者。 阅读详情

        所谓智能指针是“行为像指针”的对象,并提供指针没有的机能。例如条款13曾经提及std::auto_ptr和tr1::shared_ptr如何能够被用来在正确时机自动删除heap-based资源。STL容器的迭代器几乎总是智能指针;无疑地你不会奢望使用“++”将一个内置指针从linked list的某个节点移到另一个节点,但这在list::iterators身上办得到。

        真实指针做得很好的一件事是,支持隐式转换。Derived class指针可以隐式转换为base class指针,“指向non-const对象”的指针可以转换为“指向const对象” ......等等。下面是可能发生于三层继承体系的一些转换:

class Top { ... };
class Middle: public Top { ... };
class Bottom: public Middle { ... };
Top* pt1 = new Middle;                // 将Middle*转换为Top*
Top* pt2 = new Bottom;                // 将Bottom*转换为Top*
const Top* pct2 = pt1;                // 将Top*转换为const Top*

        但如果想在用户自定的智能指针中模拟上述转换,稍稍有点麻烦。我们希望以下代码通过编译:

template<typename T>
class SmartPtr {
    public:                                          // 智能指针通常以内置指针完成初始化
    explicit SmartPtr(T* realPtr);
    ...
};
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle);   // 将SmartPtr<Middle>转SmartPtr<Top>
SmartPtr<Top> pt2 = SmartPtr<Bottom>(new Bottom);   // 将SmartPtr<Bottom>转SmartPtr<Top>
SmartPtr<const Top> pct2 = pt1;                     // 将SmartPtr<Top>转SmartPtr<const Top>

        但是,同一个template的不同具现体之间并不存在什么与生俱来的固有关系(译注:这里意指如果以带有base-derived关系的B,D两类型分别具现化某个template,产生出来的两个具现体并不带有base-derived关系),

        在上述智能指针实例中,每一个语句创建了一个新式智能指针对象,所以现在我们应该关注如何编写智能指针的构造函数,使其行为能够满足我们转型需要。一个很关键的观察结果是:我们永远无法写出我们需要的所有构造函数。在上述继承体系中,我们根据一个SmartPtr<Middle>或一个SmartPtr<Bottom>构造出一个SmartPtr<Top>,但如果这个继承体系未来有所扩充,SmartPtr<Top>对象又必须能够根据其他智能指针构造自己。假设日后添加了:

class BelowBottom: public Bottom { ... };

        我们因此必须令SmartPtr<BelowBottom>对象得以生成SmartPtr<Top>对象,但我们当然不希望一再修改SmartPtr template以满足此类需求。

        就原理而言,此例中我们需要的构造函数数量没有止尽,因为一个template可被无限量具现化,已致生成无限量函数。因此,似乎我们需要的不是为SmartPtr写一个构造函数,而是为它写一个构造模板。这样的模板是所谓member function templates,其作用是为class生成函数:

template<typename T>
class SmartPtr {
public:
    template<typename U>                  // member template,
    SmartPtr(const SmartPtr<U>& other);   // 未来生成copy构造函数
    ...
};

        以上代码的意思是,对任何类型T和任何类型U,这里可以根据SmartPtr<U>生成一个SmartPtr<T>——因为SmartPtr<T>有个构造函数接受一个SmartPtr<U>参数。这一类构造函数根据对象u创建对象t,而u和v的类型是同一个template的不同具现体,有时我们称之为泛化copy构造函数。

        上面的泛化copy构造函数并未被声明为explicit。那是蓄意的,因为原始指针类型之间的转换(例如从derived class指针转为base class指针)是隐式转换,无需明白写出转型动作(cast),所以让智能指针效仿这种行径也属合理。在模板化构造函数中略去explicit就是为了这个目的。

        完成声明之后,这个为SmartPtr而写的“泛化copy构造函数”提供的东西比我们需要的更多。是的,我们希望根据一个SmartPtr<Bottom>创建一个SmartPtr<Top>,却不希望根据一个SmartPtr<Top>创建一个SmartPtr<Bottom>,因为那对public继承而言(见条款32)是矛盾的。我们也不希望根据一个SmartPtr<double>创建一个SmartPtr<int>,因为现实中并没有“将int* 转换为double*”的对应隐式转换行为。是的,我们必须从某方面对这一member template所创建的成员函数群进行筛除。

        假设SmartPtr遵循auto_ptr和tr1::shared_ptr所提供的榜样,也提供一个get成员函数,返回智能指针对象(见条款15)所持有的那个原始指针的副本,那么我们可以在“构造模板”实现代码中约束转换行为,使它符合我们的期望:

template<typename T>
class SmartPtr {
public:
    template<typename U>
    SmartPtr(const SmartPtr<U>& other)  // 以other的heldPtr初始化this的heldPtr
    : heldPtr(other.get()) { ... }
    T* get() const { return heldPtr; }
    ...
private:
    T* heldPtr;      // 这个SmartPtr持有内置指针
};

        我使用成员初值列来初始化SmartPtr<T>之内类型为T*的成员变量,并以类型为U*的指针(由SmartPtr<U>持有)作为初值。这个行为只有当“存在某个隐式转换可将一个U*指针转为一个T*指针”时才能通过编译,而那正是我们想要的。最终效益时SmartPtr<T>现在有了一个泛化copy构造函数,这个构造函数只在其所获得的实参隶属适当(兼容)类型时才通过编译。

        member function templates的效用不限于构造函数,它们常扮演的另一个角色是支持赋值操作。例如TR1的shared_ptr(见条款13)支持所有“来自兼容之内置指针、tr1::shared_ptrs、auto_ptrs和tr1::weak_ptrs(见条款54)”的构造行为,以及所有来自上述各物(tr1::weak_ptrs除外)的赋值操作。下面是TR1规范中关于tr1::shared_ptr的一份摘录。

template<class T>
class shared_ptr {
public:
    template <class Y>                 
     explicit shared_ptr(Y* p);                        // 构造,来自任何兼容的内置指针
    template <class Y>
     shared_ptr(shared_ptr<Y> const& r);               // 或shared_ptr
    template <class Y>
     explicit shared_ptr(weak_ptr<Y> const& r);        // 或weak_ptr
    template <class Y>
     explicit shared_ptr(auto_ptr<Y>& r);              // 或auto_ptr
    template <class Y>                                 
     shared_ptr& operator=(shared_ptr<Y> const& r);    // 赋值,来自任何兼容的shared_ptr
    template <class Y>
     shared_ptr& operator=(auto_ptr<Y>& r);            // 或auto_ptr 
    ...
};

        上述所有构造函数都是explicit,唯有“泛化copy构造函数”除外。那意味从某个shared_ptr类型隐式转换至另一个shared_ptr类型是被允许的,但从某个内置指针或从其他智能指针类型进行隐式转换则不被认可(如果是显示转换和cast强制转型动作倒是可以)。另一个趣味点是传递给tr1::shared_ptr构造函数和assignment操作符的auto_ptrs并未被声明为const,与之形成对比的则是tr1::shared_ptrs和tr1::weak_ptrs都以const传递。这是因为条款13说过,当你复制一个auto_ptrs,它们其实被改动了。

        member templates并不改变语音规则,而语言规则说,如果程序需要一个copy构造函数,你却没有声明它,编译器会为你暗自生成一个。在class内声明泛化copy构造函数并不会阻止编译器生成它们自己的copy构造函数,所以如果你想要控制copy构造函数的方方面面,你必须同时声明泛化copy构造函数和“正常的”copy构造函数。相同规则也适用于赋值操作。下面是tr1::shared_ptr的一份定义摘要,例证上述所言:

template<class T>
class shared_ptr {
public:
    shared_ptr(shared_ptr const& r);    // copy构造函数

    template <class Y>
     shared_ptr(shared_ptr<Y> const& r);               // 泛化copy构造函数
                
     shared_ptr& operator=(shared_ptr<Y> const& r);    // copy assignment
    template <class Y>
     shared_ptr& operator=(shared_ptr<Y> const& );     // 泛化copy assignment
    ...
};

请记住

  • 请使用member function templates(成员函数模板)生成“可接受所有兼容类型”的函数。
  • 如果你声明member templates用于“泛化copy构造”或“泛化assignment操作”你还是需要声明正常的copy构造函数和copy assignment操作符。
Qt5+Ros+GUI界面 在之前建立的工程的基础上添加一个gui界面。 在ros包中新建一个文件夹,名字叫gui 右击gui文件夹添加一个文件,选择Qt->Qt设计师界面类 选择MainWindow 选择下一步 最后在gui中生成三个文件 mainwindow.cpp、mainwindow.h、mainwindow.ui 但此时,这些新创建的文件和原本的ros工程还没建立任何关系,只是目录下多出了几个文件而已... 阅读详情

相关推荐

开源实战 | 基于SolidWorks与Matlab的并联索驱机器人轨迹规划全流程

本文详细介绍了基于SolidWorks与Matlab的并联索驱机器人轨迹规划全流程,涵盖从基础概念到实战技巧的各个环节。通过SolidWorks建模、Matlab运动学实现及轨迹优化策略,展示了如何实现高精度轨迹规划,适用于摄影、医疗等领域的机器人应用。

weixin_28331555的博客 402

条款45:运用成员函数模板接受所有兼容类型

所谓智能指针(smart pointers)是”行为像指针“的对象,并提供指针没有的机能,比如条款13提到的std::auto_ptr和trl::shared_ptr如何被用来在正确时机自动删除heap-based资源。STL容器的迭代器几乎总是智能指针。但如果想在用户自动逸的智能指针中模拟上述转换,稍微有点麻烦。但。

依然爱猪的博客 2243

【spark源码修改】hive3.1.3 spark3.5.4编译,需要修改源码,最终编译成功

【spark源码修改】hive3.1.3 spark3.5.4编译,需要修改源码,最终编译成功,附带问题分析详细过程

spark_dev的博客 1911

Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型

Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型 首先理解标题的含义 真实指针是支持隐式转换的,智能指针是行为像指针的对象,并且提供指针没有的机能。现在我们想如何编写智能指针的构造函数,使其行为能够满足我们的转型需求。因为一个template可以无限量具现化,所以我们无法写出我们需要的所有构造函数,我们解决问题的方法是不是为智能指针写一个构造函数,而是直接为其写一个构造模板。 template<typename T> class SmartPtr{ public:

weixin_46388214的博客 185

C#与西门子PLC通讯——新手快速入门

本文基于C# .Net Core和西门子博图TIA Portal V17搭建。由于手边没有西门子PLC实物,所以采用S7-PLCSIM Advanced V4.0作为模拟PLC,以实现0成本完成通讯测试实例。这篇入门笔记解决了新手第一次上手实践时遇到的坑,并且有意忽略了实际项目中会遇到的逻辑交互和更多的数据格式问题。

吾家有猫名探花的博客 2万+

ChatGPT Plus完整开通指南:从账号注册到稳定使用全流程

自然语言处理(NLP)技术通过深度学习模型实现对人类语言的理解与生成,其核心原理是基于Transformer架构的大规模预训练。GPT-4作为当前最先进的生成式AI模型,在代码编写、文档分析等场景展现出显著的技术价值。在实际应用中,稳定的网络环境和合规的支付方式是确保AI助手持续服务的关键因素。针对ChatGPT Plus的开通,需要系统性地解决账号验证、虚拟信用卡支付等工程实践问题,才能实现工作流的高效整合。

weixin_34239592的博客 426

Effective C++之 Item 45: 用 member function templates(成员函数模板) 接受 "all compatible types"(“所有兼容类型”)

smart pointers(智能指针)是行为很像指针但是增加了指针没有提供的功能的 objects。例如,Item 13 阐述了标准 auto_ptr 和 tr1::shared_ptr 是怎样被应用于在恰当的时间自动删除的 heap-based resources(基于堆的资源)的。STL containers 内的 iterators(迭代器)几乎始终是 smart pointers(智能...

janeqi1987的专栏 234

【实战指南】EC-Engineer中ESI配置与PDO Mapping全流程解析

本文详细解析了EC-Engineer中ESI配置与PDO Mapping的全流程操作,包括环境准备、ESI文件导入技巧、在线配置细节及故障处理。特别强调了WinPcap驱动的兼容性问题和PDO Mapping的最佳实践,帮助工程师高效完成EtherCAT总线配置,适用于工业自动化领域的伺服控制与运动协同场景。

weixin_28730927的博客 394

条款45:运用成员函数模板接受所有兼容类型。

  生命了一个泛化copy构造函数,当类型T和Y相同时,泛化copy构造函数会被具现为“正常的”copy构造函数。那么究竟编译器会暗自生成一个copy构造函数?或当某个tr1::shared_ptr对象根据另一个同型的tr1::shared_ptr对象展开构造行为时,编译器会将“泛化copy构造函数模板”具现化呢?  如果自己不定义的copy构造函数的话,就会调用泛化copy构造函数,如果自己

孟游的专栏 535

数字滤波器应用介绍

线性滤波器FIR ,会引起恒定延迟,通过补零的方式补偿非线性滤波器IIR,会引起频率相关的延迟,通过零相位延迟filtfilt补偿从信号中去除不需要的频谱时,通过滤波和补偿实现。如果需要去除的频率与采样率相差甚远,比如4kHz 与100Hz, 可通过 低通滤波->补偿->降采样–> 滤波 补偿 -->上采样还原的方法。*降采样前一定要先低通滤波为了防止混叠。

weixin_39107270的博客 274

YOLO11 锚框机制全解析:从改进 K-means 聚类到自适应优化,附多场景实战(附代码)

摘要 YOLO11的锚框机制采用"自适应、动态化、场景感知"的设计理念,通过数据驱动的锚框生成、多尺度感知分配和实时优化策略,显著提升目标检测性能。相较于早期YOLO版本,YOLO11的锚框完全基于训练集目标分布自适应生成,并引入智能分配策略,使不同尺寸目标获得最优匹配。技术架构包含自适应锚框生成、多尺度分配器和动态优化模块,通过改进的K-means聚类和交并比计算实现精准匹配。YOLO11锚框机制在检测精度、训练稳定性和场景适应性方面均有显著提升,为复杂场景下的目标检测提供更优解决方案

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1318

运用成员函数模板接受所有兼容类型

template class shared_ptr { public: template // 构造,来自任何兼容的 explicit shared_ptr(Y* p); //内置指针 template shared_ptr(shared_ptr const&

享受开发技术,享受计算机科学 881

基于机器学习的网络入侵检测系统设计与实现

本文设计并实现了一个基于机器学习的网络入侵检测系统,采用随机森林模型结合KMM算法优化,使用CICIDS2017数据集进行训练。系统包含完整的数据预处理流程、特征工程、模型调优和远程部署方案。实验结果表明,该系统能有效识别多种网络攻击类型,在检测准确率和误报率方面表现优异。研究为网络安全防护提供了新的技术思路和实用工具,具有重要的应用价值。

huanghm88的专栏 315

[Effective C++]条款45 运用成员函数模板接受所有兼容类型

本条款中我们将会以智能指针为例, 介绍如何通过成员函数模板使一个模板类可以接受所有兼容类型.

tianmu_sama的博客 721

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

条款45:运用成员函数模板接受所有兼容类型

条款44:运用成员函数模板接受所有兼容类型(Use member function templates to accept "all compatible types.")内容:    不知道大家注意到没有,在类的继承体系中,对象指针一直在为我们做一件很好的事情:支持隐式转换(implicit conversions).Derived class指针可以隐式转换为base class指针,"指

scofieldzhu的专栏 969

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

条款45:运用成员函数模板接受所有兼容类型——248

文章目录Template和泛型编程——249总结——252 Template和泛型编程——249 我们来构造一个成员函数模板: template<typename T> class SmartPtr{ public: template<typename U> SmartPtr(const SmartPtr<U>& other); ...

缇珞的博客 231

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Effective C++ 条款45:运用成员函数模板接受所有兼容类型

学习使用成员函数模板实现泛化拷贝构造和赋值操作,让自定义类型支持所有兼容类型的隐式转换。

凡人叶枫的博客 209

条款45: 运用成员函数模板接受所有兼容类型

真实指针做得很好的一件事是,支持隐式转换(implicit conversions),比如如下代码: class Top {}; class Middle : public Top {}; class Bottom : public Middle {}; Top *pt1 = new Middle; // 将Middle转化为Top* Top *pt2 = new Bottom; // 将Bottom转化为Top* const Top *pct2 = pt1; // 将Top*转化为const

L_H_L的博客 182

Effective C++条款45:运用成员函数模板接受所有兼容类型

智能指针是行为像指针的对象,真的指针做的很好的事情是:支持隐式转换,派生类指针可以隐式转换为基类指针,指向non-const对象的指针可以转换为指向const对象等等,比如: class Top {...}; class Middle : public Top{...}; class Bottom : public Middle{...}; Top * t1 = new Middele; Top ...

qq_44800780的博客 254

EffectiveC++-条款45:运用成员函数模板接受所有兼容类型

## 一. 内容 1. 我们从例子入手,所谓智能指针(smart pointer),是行为像指针的对象,并提供指针没有的机能:自动管理资源。但原始指针(raw pointer)做的很好的一件事是:支持隐式转换(implicit conversions)。比如 derived class 指针可以隐式转换为 base class 指针,指向 non-const 的指针可以转换为 指向 const 的指针... 而对于 template 具现的类,并不能很好的进行像原始指针一样的隐式转换,比如想把一个具现类

MoOtA 269

【Effective C++】条款45: 运用成员函数模板接受所有兼容的类型

经过分析,可以发现,关键点在于拷贝构造函数,只要拷贝构造函数能复用编译器关于类型向上/向下,显式/隐式的转换规则,那我们的SmartPtr就可以模拟上面提到的类型转换.public继承意味着is-a关系,所有的基类都是派生类,但反之则不是,例如所有的学生都是人,但不是所有的人都是学生.但假设,我们写了一个智能指针类,当此智能指针的模板参数是这些类的时候,如何才能实现上述继承结构下的隐式转换呢?当我们使用了函数模板兼容了所以的类型后,如果模板类型参数T和U的类型相同,例如。此时两个对象的类型都相同,都是。

apkjdk的博客 291

Effective C++条款45:模板与泛型编程之(运用成员函数模板接受所有兼容类型)

待续

董哥的黑板报 876

Effective C++ 条款45 运用成员函数模板接受所有兼容类型

1. "智能指针"是行为像指针的对象,但它们能提供指针没有的功能:shared_ptr,weak_ptr,auto_ptr(见条款13)实现对堆内存的自动管理,STL的迭代器实现对整个容器的遍历等. C++内置类型指针(int*,char*等)的优势在于支持继承层次中派生类指针向基类指针的转换(当然标准库shared_ptr,weak_ptr,auto_ptr等已实现). 2...

ddzai7557的博客 172

条款45:运用成员函数模板接受所有兼容类型;条款46:需要类型转换时为模板定义非成员函数

条款45:运用成员函数模板接受所有兼容类型 例: template<typename T> class A{ public: template<typename Y> void func1(A<Y>& y1); A(const A& a); //复制构造函数 template<typename Y> A(const A&...

个人工作中学到的专业技术与职业发展知识笔记 208

Effective C++条款45:模板与泛型编程——运用成员函数模板接受所有兼容类型

一、添加成员函数模板 以一个例子引出,何时设计成员函数模板 第一步:我们知道指针的一个特点就是:支持隐式转换。例如“指向non-const对象的指针可以转换为指向const对象”,“派生类指针可以隐式转换为基类指针”等等。代码如下: class Top {}; class Middle :public Top {}; class Bottom :public Middle {}; Top* pt1 = new Middle; //将Miffle*转换为Top* Top* pt2 = new

www_dong的博客 282
上一篇: 将与参数无关的代码抽离templates——条款44
下一篇: 需要类型转换时请为模板定义非成员函数——条款46
OODeveloper
博客等级 码龄12年 43粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值