根据策略禁用了文件传输_Hands-On Design Patterns With C++(十六)基于策略的设计(四)...

本文探讨了如何使用C++的策略设计模式来控制类的公共接口,通过SFINAE原则有条件地启用或禁用成员函数。内容包括如何根据策略禁用文件传输,以及如何在更改主模板类型时重新绑定策略,确保相关策略类型一同更新。文章通过智能指针类的示例详细解释了这些高级技巧。
摘要由CSDN通过智能技术生成

be34b9037c1922b95757c452ca41e340.png

目录:

trick:Hands-On Design Patterns With C++(零)前言​zhuanlan.zhihu.com
e211206e0775e6a9ba2be20740b52319.png

本文提要:本文介绍两个方面:(1)对公共接口的控制,即根据不同条件打开或关闭公共接口。(2)重新绑定策略,即如果更改主模板类型,如何连相关的策略类型一并更新。

基于策略设计的高级技巧

使用策略控制公共接口(public interface)

前面我们已经使用过一种策略控制公共接口的方式。我们通过从策略继承来注入公共成员函数(参考第二篇WithRelease增加公共接口)。这种方法相当灵活且功能强大,但是有两个缺点

  1. 一旦我们从策略类公有继承,我们就无法控制注入的接口,策略的每个公共函数都是派生类就口的一部分!
  2. 如果要使接口生效,我们不得不将策略类强转为派生类,它还必须有权访问所有数据成员及派生类继承的其他策略。

现在,我们学习一种更直接的方法来操纵基于策略的类公共接口。 首先,让我们区分两个概念:有条件地禁用现有成员函数添加新成员函数

  1. 前者(有条件地禁用现有成员函数)是合理且安全的:如果特定实现不支持接口提供的操作,则就不应该提供此接口。
  2. 后者(添加新成员函数)是危险的:它使类公共接口的扩展失控。

所以,我们应该为策略类提供必要的接口,并禁用无关的接口。

C++有方法有选择地启用和禁用成员函数,我们经常通过std::enable_if实现,其基础是我们在第7章讲到的SFINAE与重载解析管理(Substitution Failure Is Not An Error 替代失败不是错误)。

为了说明使用SFINAE实现策略可以有选择地启用/禁用成员函数,我们通过有选择地禁用智能指针类中的operator->()来进行示范。

首先,让我们回顾一下std::enable_if如何启用或禁用特定成员函数:如果表达式std::enable_if <value, type>结果为true,则将编译并产生指定的类型;如果值为false,则类型替换失败(不生成任何类型结果)。 此模板元函数的正确用法是在SFINAE上下文中,其中类型替换失败不会导致编译错误,而只是禁用失败的函数(更确切地说,它将其从重载解决方案集中删除) 。

由于使用SFINAE启用或禁用成员函数所需的全部是编译时常量,因此可以使用constexpr值定义其他策略:

struct WithArrow {
    
    static constexpr bool have_arrow = true;
};
struct WithoutArrow {
    
    static constexpr bool have_arrow = false;
};

现在,我们可以使用std::enable_if配合策略来控制是否产生operator->()公共接口,如果为true,返回T*,否则类型推倒失败:

// 使用允许->操作符策略
// 这种写法如果将ArrowPolicy设置为WithoutArrow,即使不使用operator->(),也无法通过编译!
template <typename T, typename DeletionPolicy = DeleteByOperator<T>, typename ArrowPolicy = WithArrow>
class SmartPtr : private DeletionPolicy {
    
public:
    // 使用enable_if决定是否允许operate->(),如
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值