您的位置:首页 > 编程语言 > C语言/C++

Effective C++ 条款43

2015-06-05 16:15 330 查看
学习处理模板化基类里的名称

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

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

#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绑定行为,慎用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: