Effective C++ 学习笔记(六)

本文详细解析了C++中类和模板支持的接口与多态特性,包括显式接口和运行时多态在类中的应用,以及模板参数的隐式接口和编译时多态的实现。此外,文章还探讨了typename的双重意义,以及如何正确处理模板化基类内的名称,防止特化模板中的方法调用错误。最后,提供了将无关代码抽离模板、运用模板接受兼容类型的方法,以及如何避免代码膨胀的策略。
摘要由CSDN通过智能技术生成

条款41:了解隐式接口和编译器多态

(1)classes和template都支持接口和多态,对class而言接口是显式的,以函数签名为中心,多态则是通过virtual函数发生于运行期,对template参数而言,接口是隐式的,奠基于有效表达式,多态则是通过template具现化和函数重载解析发生于编译器。

条款42:了解typename的双重意义

(1)typename和class在template<typename T>这样的用法是相同的

(2)typename还有一个特别的用法,因为使用模版的类是一个不确定的类,如果我们使用了不确定类的不确定成员变量,这种情况我们要在前面加上typename,如

template <typename T> class B
{
    typename T::const_iterator iter; //
};
因为const_iterator是一个迭代器,我们默认我们以后为T传进去的参数是一个容器,在这种情况下const_iterator就是一个不确定类的不确定成员变量(也称嵌套从属类型),就需要在前面加上typename。但是有两个例外,第一就是typename不可以出现在base class list内的嵌套从属类型名称之前,也不可在成员初值列中作为base class修饰符。

条款43:学习处理模版化基类内的名称

(1)在模版的子类中调用父类的方法会编译不通过,如下例所示:

#include<iostream>
using namespace std;

class CompanyA
{
public:
    void sendCleartext( const string& msg );
    void sendEncrypted( const string& msg );
};
class CompanyB
{
public:
    void sendCleartext( const string& msg );
    void sendEncrypted( const string& msg );
};
....//针对其他公司设计的classes

class MsgInfo{...};//用来保存信息,以备将来产生信息

template<typename Company>
class MsgSender
{
public:
    void sendClear( const MsgInfo& info )
    {
        string msg;
        // 在这,根据info产生信息
        Company c;
        c.sendCleartext( msg );
    }
    void sendSecret( const MsgInfo& info )
    {
        ...//类似于sendClear
    }
};
template<typename Company>
class LoggingMsgSender:public MsgSender<Company>
{
public:
    void sendClearMsg( const MsgInfo& info )
    {
        //将传送前的信息写至log
        sendClear( info ) ;//错误的代码,可能特化的模版就没有这个函数
        //将传送后的信息写至log
    }
};

导致这样的结果的原因是,模版存在特化的情况,在LoggingMsgSender中调用父类MsgSender中的方法sendClear的时候会报错,是因为如果父类如果存在特化,并且特化的类中没有这个函数那么就将导致错误,为了防止这种错误的发生,C++编译器就会在编译的时候防止这种事情发生,报错。

为了解决上述问题,C++可以采用3中解决办法,这些解决办法的实质是向编译器承诺该方法是存在的,第一:在base class函数调用动作之前加上“this->”,第二:使用using声明式。如:using MsgSender<Company>::sendClear,第三:明白的指出被调用的函数位于base class内,MsgSender<Company>::sendClear()

条款44:将于参数无关的代码抽离template

(1)template容易导致代码膨胀,而且不易发现,所以为了防止template代码膨胀可以采用将共用的一些方法抽离出来,组成基类。

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

(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值