zoukankan      html  css  js  c++  java
  • 高效C++:模板和泛型编程

      模板和泛型编程的关注重点在编译期,所有的行为都在编译期确定,因此其规则和玩法也有自己特殊的一套,和其他模块不通用。

     

    了解隐式接口和编译期多态

    • 元编程------编译器多态,决定哪个重载函数被调用

    • class的特点:

      • 显示接口

      • 运行期多态

    • template的特点:

      • 隐式接口

      • 编译器多态,模板的具现和函数的重载

    了解typename的双重含义

    • 声明template参数时,前缀关键字class和typename可以互换

    • 使用typename关键字声明嵌套从属类型名称,但不可以出现在基类列表和初始化里列表中

    • 嵌套从属名称

    template<typename C>
    void Print2Nd(const C& container)
    {
        ...
       typename C::const_iterator iter(container.begin()) //确认是类型不是名称
        ...    
    }
    
    //C::const_iterato 从属嵌套类型(名称中依赖于template类型参数)

    学习处理模板化基类内的名称

    • 在Derived class template中调用base class template的函数时,直接调用编译不过,可以使用如下方法:

      • this->xxx (建议)

      • basename::xxx

      • using basename::xxx

    class CompanyA{
    public:
        CompanyA(){}
    
        void Send()
        {
            cout<<"CompanyA::Send()"<<endl;
        }
    };
    
    class CompanyB{
    public:
        CompanyB(){}
    
        void Send()
        {
            cout<<"CompanyB::Send()"<<endl;
        }
    };
    
    template<typename Company>
    class Sender{
    public:
        Sender(){}
        
        void SendMsg()
        {
            Company c;
            c.Send();
        }
    };
    
    
    template<typename Company>
    class LogSender: public Sender<Company>
    {
    public:
        using Sender<Company>::SendMsg;  
    
        void LogSendMsg()
        {
            cout<<"LogSender::LogSendMsg() before"<<endl;
            
            SendMsg();  //单独使用错误,配合using使用ok
            this->SendMsg(); //OK
            Sender<Company>::SendMsg(); //OK
            
            cout<<"LogSender::LogSendMsg() after"<<endl;
        }
    
    };

    将与参数无关的代码抽取template

    • 不要将函数参数提取为template,这样导致代码冗余

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

    • 使用模板成员函数生成可接受和兼容所有类型的函数,包括构造函数

    template<typename U>
    class A
    {
    public:    
        template<typename T>
        A(A<T>& other)
        {
            ...
        }
    };
    • 如果将构造函数声明为模板函数,为了阻止编译器生成默认的构造函数,你必须明确声明一个非模板的构造函数

    需要类型转换时请为模板定义非成员函数

    • template在推倒虑隐式转换

    • 对比“定义no-member函数进行类型转换”这一条规则

    template<typename T>
    const Rational<T> doMutliply(const Rational<T>& lhs, const Rational<T>& rhs)
    {
        ...
    }
    
    template<typename T>
    class Rational
    {
    public:
        ...
        //声明为friend函数的目的是tempalte推倒,保证编译通过,根本目的是提供一个使用是所有类型的乘法   
        frined const Rational<T>operator*(const Rational<T>& lhs, const Rational<T>& rhs)
        {
            return doMutliply(lhs, rhs);
        } 
    }

    请使用traits classes表现类型信息

    • 需要了解STL编程,可以参考《STL源码剖析》一书

    • 运用到模板、元编程等知识

    了解template元编程

    • 元编程将运行期的工程提前到编译期,错误的发现更早,效率更高

  • 相关阅读:
    zabbix3.4监控Windows-CPU使用率磁盘IO磁盘监控阈值邮件报警详细配置
    网站打开提示Service Unavailable如何解决?
    windows服务器下zabbix agent的安装调试
    如何判断自己的VPS是那种虚拟技术实现的?
    win7/win10下KiWi Syslog服务器的安装与配置
    centos7.x内核参数优化脚本
    centos7.6更改主机名为FQDN格式不生效解决办法
    chmod: changing permissions of 'xxx': Operation not permitted
    编译安装nginx提示./configure: error: C compiler cc is not found
    centos7利用系统镜像修复grub
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11452786.html
Copyright © 2011-2022 走看看