zoukankan      html  css  js  c++  java
  • Effective C++ 条款45

    本节条款的题目是运用成员模板接受全部兼容类型

    作者阐述自己的观点是通过智能指针的样例。
    在学习本节条款之前我们要先明确关于隐式转化的问题
    例如以下代码:

    #include<iostream>
    using namespace std;
    class A
    {
    public:
        explicit A(int i):a(i){};
        A(const A&obj):a(obj.a)
        {
        }
    private:
        int a;
    };
    
    
    int main()
    {
        int value =0;
        A a = value;//编译不通过。由于构造函数中有explicit限定符
        return 0; 
    
    }

    我们知道由于explicit限定符的存在编译不通过。
    以下我们看另一段书上的代码:

    template<typename T>
        class SmartPrt{
        public:
            explicit SmartPtr(T* realPtr);
            ……
        };
        SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);
        SmartPrt<Top> pt2=SmartPrt<Bottom>(new Bottom);
        SmartPrt<const Top> pct2=pt1;
    我们能够知道,由于`SmartPtr<Top>`类型和`SmartPtr<Middle>`
    

    类型不同。再加上explicit SmartPtr<Middle>中的explicit限定符,SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);这句代码编译不通过。
    并且编译器并不觉得SmartPtr<Top>类型和SmartPtr<Middle>类型存在继承关系。
    为了能够实现相互转化。能够加入本节的主旨技术去解决上面出现的问题。
    例如以下代码:

     template<typaname T>
        class SmartPtr{
        public:
            template<typename U>
            SmartPrt(const SmartPrt<U>& other)
            :heldPrt(other.get()){};
            T* get() const{return heldPrt;}
            ……
        private:
            T* heldPrt;
        };
    
        SmartPtr<Top> pt1=SmartPtr<Middle>(new Middle);
        SmartPrt<Top> pt2=SmartPrt<Bottom>(new Bottom);
        SmartPrt<const Top> pct2=pt1;

    我们加入了一个member function template函数。由于typename T和typename U 是两种类型,并且构造函数中没有explicit关键字,不会阻止heldPrt(other.get())的隐式转换

    所以,以上代码能够通过编译。

    作者最后列出了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);
            template<class Y>
                explicit shared_ptr(weak_ptr<Y> const& r);
            template<class Y>
                explicit shared_ptr(auto_ptr<Y> const& r);
            template<class Y>
                shared_ptr& operator=(shared_ptr<Y> const& r);
            template<class Y>
                shared_ptr& operator=(auto_ptr<Y> const& r);
            ……
        };

    我们能够发现上面仅仅有泛化copy构造函数不是explicit,表示shared_ptr 的隐式转化被同意,而其它的智能指针转化不被同意。

    这里另一个须要注意的地方,在class类声明泛化copy构造函数(member template)。并不会阻止编译器生成它们自己的copy构造函数(non-template),换言之。假设程序中仅仅写了泛化的copy构造函数,那么编译器还是会自己主动生成一个非泛化的版本号出来,假设不想要这个缺省版本号,那一定不能偷懒。要两个版本号的copy构造函数都要写。
    代码例如以下:

    template<typaname T>
        class SmartPtr{
        public:
            template<typename U>
            SmartPrt(const SmartPrt<U>& other)
            :heldPrt(other.get()){};
            SmartPtr(){}//假设不写自己的非泛化构造函数,编译器会自己主动生成自己的默认非泛化构造函数。
            T* get() const{return heldPrt;}
            ……
        private:
            T* heldPrt;
        };

    最后:
    作者总结例如以下:
    1. 请使用member function templates(成员函数模板)生成“可接受全部兼容类型”的函数。
    2. 假设你声明member templates用于“泛化copy构造”或“泛化assignment操作”,你还是须要声明正常的copy构造函数和copy assignment操作符。

  • 相关阅读:
    算法题汇集
    C# WinForm MDI左右分栏 多文档
    DDoS和CC攻击的区别
    搭建java程序写的博客Jpress
    U盘图标DIY方法
    磁盘空间不够用?教你一键清理电脑重复文件Duplicate File Finder
    给WordPress文章页URL赋予.html后缀
    使用七牛云和PicGo搭建图床
    wordpress好用的Markdown插件WP Editor.MD
    虚拟主机、VPS、云服务器三者的区别
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5358702.html
Copyright © 2011-2022 走看看