条款41、隐式接口和编译期多态

本文探讨了C++模板的起源和发展,特别是在容器设计中的应用。深入分析了模板与面向对象编程的区别,特别是隐式接口和编译期多态的概念。
	C++ template最初的发展动机:建立“类型安全type safe”的容器如vector,lis,map.后面随着使用的增多,我们发现模版有能力完成更多可能的变化。
	容器虽好,但泛型编程(generic programming)更好:代码和其所处理的对象类型彼此独立。STL算法如for_each,find等就是这类编程的成果。
	于是导出了模板元编程(tmplate metaprogramming):”C+编译器内执行,并于编译完成时停止执行”
面向对象编程总是以显式接口(explicit interfaces)和运行期多态(runtime polymorphism)解决问题.
class Widget
{
         public:
         Widget();
         virtual  ~Widget();
         virtual std::size_t size()const;
         virtual void normalize();
         void swap(Widget&other);    //TK25
}
void doProcess(Widget& w) //无意义的函数
{
         if(w.size()>10&&w!=someNastyWidget)
{
         Widget tmp(w);
         tmp.normalize();
         tmp.swap(w);
}
} //我们可以说doProcess内的w

从上面代码中我们知道:
1、w的类型被声明为Widget,w必须支持Widget接口。我们可以在源码中找到这个接口(Widget的.h文件)。我们称此为一个显示接口、即它在源码中明确可见
2、Widget的成员函数有virtual的,w对那些函数表现出运行时多态。即根据动态类型决定调用哪一个函数。
模版和范型编程与面向对象有根本上的不同,虽然显示接口和运行多态依然存在,但重要性变低。而隐式接口和编译期多态相对更重要。考虑以下代码:
template<typename T>
void doProcess(T& w) {
         if(w.size()>10&&w!=someNastyWidget)
{
         T  tmp(w);
         tmp.normalize();
         tmp.swap(w);
}
}

从上述代码我们可以知道:
1、w支持哪种接口,由模版执行于w上的操作决定。如本例中w必须支持size,normalize,swap,copy构造、不等比较等(虽然不完全正确)。这组表态式(对该模板而言必须有效编译)是T必须支持的一组隐式接口。
2、涉及w的调用,可能实例化模板。“以不同的模板参数实例化函数模版”会导致不同的函数调用。这就是所谓的编译期多态
类似于“哪一个重载函数被调用”(发生在编译期)和“哪一个虚函数被绑定”(运行期)。
 
通常显式接口由函数签名式(函数名,参数类型、返回类型)构成.如
class Widget
{
         public:
         Widget();
         virtual  ~Widget();
         virtualstd::size_t size() const;
         virtualvoid normalize();
         void swap(Widget&other);    //TK25
}

如上,public接口由一个构造、一个析构、三个函数及其参数类型、返回值、常量性构成。当然也包括编译产生的复制构想和copy assignmeng操作符。当然也可以也包括typedef等。
隐式接口完全不同,并不基于签名式,而是由有效表达式组成。再次看下面函数模版的初始条件:
template<typename T>
void doProcess(T& w) {
         if(w.size()>10&&w!=someNastyWidget)
         ……
}

T的隐式接口似乎有这些约束
1、它必须提供一个size函数,该函数返回一个整数值。
2、必须支持一个operator!=  函数,用于比较两个T对象。这里我们假设someNastyWidget类型为T

	这要感谢操作符重载带来的可能性,这两个约束都不需要满足。虽然T必须要支持size函数,但这个函数可以从基类继承而来。同时这个成员函数甚至不要返回一个整数值或整数类型,更甚至不要定义operator>操作类型。唯一要做的是返回一个X对象,这个对象加个一个int(10)的类型就能调用一个operator>。同时operator不需要非取得一个类型为X的参数不可,也可以取得类型为Y的参数,只需要一个隐式转换可以将X转换成Y对象。
         同理类推:T并不需要支持operator=,因为这样也是可以的:operator!= 接受一个类型为X和类型为Y的对象,T可以转换为X而someNastyWidget可以转换为Y。这样就可以直接调用operator!=

上面表达方式或许很复杂,但实际而言却不是,因为它们的约束条件相当直接又明确。如:
if(w.size()>10&&w!=someNastyWidget)

	如其约束条件,虽然多,但整体却很容易。if条件式必须是个bool表达式。无论涉及什么也无论表达式导致什么,只需与bool兼容就行了。这是模版函数doProcess加诸于其他类型参数T的隐式接口的一部分。该函数要求的其他隐式接口:如copy构造、normalize、swap也必须对T型对象有效。

	模版参数身上的隐式接口,和类对象身上的显式接口一样。都在编译期间完成检查。“与类提供显示接口矛盾”的方式使用对象    和   在模版中使用“不支持模版要求的隐式接口”对象都不能通过编译。

需要记住的:
	1、类和模版都支持接口和多态。
	2、类接口是显示的,以函数声明为中心。多态通过虚函数发生于运行期。
	3、对模版参数而言,接口是隐式的,基于有效表达式。多态通过模版实例化和函数重载解析,发生于编译期。

【多变量输入超前多步预测】基于CNN-BiLSTM的光伏功率预测研究(Matlab代码实现)内容概要:本文介绍了基于CNN-BiLSTM模型的多变量输入超前多步光伏功率预测方法,并提供了Matlab代码实现。该研究结合卷积神经网络(CNN)强大的特征提取能力与双向长短期记忆网络(BiLSTM)对时间序列前后依赖关系的捕捉能力,构建了一个高效的深度学习预测模型。模型输入包含多个影响光伏发电的气象与环境变量,能够实现对未来多个时间步长的光伏功率进行精确预测,适用于复杂多变的实际应用场景。文中详细阐述了数据预处理、模型结构设计、训练流程及实验验证过程,展示了该方法相较于传统模型在预测精度稳定性方面的优势。; 适合人群:具备一定机器学习深度学习基础,熟悉Matlab编程,从事新能源预测、电力系统分析或相关领域研究的研发人员与高校研究生。; 使用场景及目标:①应用于光伏电站功率预测系统,提升电网调度的准确性与稳定性;②为可再生能源并网管理、能量存储规划及电力市场交易提供可靠的数据支持;③作为深度学习在时间序列多步预测中的典型案例,用于科研复现与教学参考。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注数据归一化、CNN特征提取层设计、BiLSTM时序建模及多步预测策略的实现细节,同时可尝试引入更多外部变量或优化网络结构以进一步提升预测性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值