• Effective C++ 条款43


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

    本节作者编写的意图在我看来能够总结成一句话,就是“怎样定义并使用关于模板类的派生过程,怎样处理派生过程出现的编译不通过问题”。

    以下我们看一段说明性的代码:

    #include<iostream>
    using namespace std;
    
    class object1
    {
    public:
        void get(){ cout << "object1"; }
        void out(){ cout << "out1"; }
    };
    
    
    class object2
    {
    public:
        void get(){ cout << "object2"; }
        void out(){ cout << "out2"; }
    };
    
    template <typename object>
    class A
    {
    public :
        void func1()
        {
            object ob;
            ob.get();
        }
        void func2()
        {
            object ob;
            ob.out();
        }
    };
    
    int main()
    {
        A<object1>a;
        a.func1();//调用object1中的get函数
        cout << endl;
        A<object2>b;
        b.func2();//调用object2中的out函数
    
    
    }

    由上面的代码能够看出template模板带给我们编程的优越性,它极大的提高了我们代码的利用率。

    但是好性能背后往往都会有一些牺牲,比方在多重继承中的编译问题。
    例如以下代码:

    #include<iostream>
    using namespace std;
    
    class object1
    {
    public:
        void get(){ cout << "object1"; }
        void out(){ cout << "out1"; }
    };
    
    
    class object2
    {
    public:
        void get(){ cout << "object2"; }
        void out(){ cout << "out2"; }
    };
    
    class object3
    {
    public:
        void out(){ cout << "out3"; }
    };
    
    
    
    template <typename object>
    class A
    {
    public :
        void func1()
        {
            object ob;
            ob.get();
        }
        void func2()
        {
            object ob;
            ob.out();
        }
    };
    
    template<> 
    class A<object3>
    {
    public:
        void func2()
        {
            object3 ob;
            ob.out();
        }
    };
    
    template <typename object>
    class B:public A<object>
    {
    public:
        void func3()
        {
            func1();
        }
    };
    

    以上代码。依照作者的意思是编译不通过,由于无法确定是否模板类template base class中有funct1()函数,我用的是vs2014编辑器,并没有出现这样的问题。所以,不知道是不是微软开发大神完好了这个编译缺点。一句话,对于。vs2014来说该条款是无效的。欢迎大神指正。
    至于。假设为什么无法编译,是由于有全特化模板的出现。如上对object3的全特化过程中并没有funct1()函数,这时假设编译器不进行阻止,在程序以后执行中就会崩溃。

    按作者的意思,假设出现以上问题,能够通过以下三种手段解决,三种方式的用意就是告诉编译器。基类中拥有派生类所需的函数。

    让编译器进入基类进行寻找。而不是在没有寻找的前提下就编译报错。
    第一种:

    template <typename object>
    class B:public A<object>
    {
    public:
        void func3()
        {
            this->func1();//加上this关键字
        }
    };

    另外一种:

    template <typename object>
    class B:public A<object>
    {
          using A<object>::func1;
    public:
        void func3()
        {
            this->func1();//加上this关键字
        }
    };

    第三种:

    template <typename object>
    class B:public A<object>
    {
    public:
        void func3()
        {
            A<object>::func1();
        }
    };

    至于第三种,会关闭virtual绑定行为,慎用。

  • 相关阅读:
    J.U.C AQS(abstractqueuedssynchronizer--同步器)
    垃圾收集器与内存分配策略---内存的分配与回收
    16.合并两个排序的链表
    15.反转链表
    14.链表中倒数第k个节点
    15.Subtree of Another Tree(判断一棵树是否为另一颗树的子树)
    flask 学习app代码备份
    TCSRM5961000
    URAL1291. Gear-wheels
    hdu4422The Little Girl who Picks Mushrooms
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6993367.html
Copyright © 2020-2023  润新知