C++模板类继承中的Name Lookup
2015-07-30 21:26
281 查看
今天这篇文章说说C++中的模板类继承时的名称(变量/类型)查找(Name Lookup)。普通的继承关系中的Name Lookup对于熟悉C++的同学来说,都是非常直观的,因此在这里就不再赘言。模板类(Template Class)的继承中,由于模板本身特殊性,使其在Name Lookup时,有着一定的特殊性,我们从一个例子来说明:
看完上面这个例子,如果有同学能一眼看出这个例子中存在的问题,那后面的内容可以不用看了,这篇文章中要讲的内容你是清楚的。如果看不出,那我们继续来看这个例子会有什么问题。我们用g++(v4.5.1)来编译上面的例子:
神马?m_data没有声明?明明不是在基类A< T>里已经声明了吗?为什么这里编译器会说没有声明呢?难道是编译器有bug?非也非也,g++/gcc是久经考验的工具,它出bug的概率肯定比我们写的程序出bug的概率要小得多,本着任何时候都要先怀疑自已的精神,我们来找寻这里的问题的答案。
我们知道,在普通的继承关系中,Name Lookup的基本顺序是先从子类里找,如果在子类里找不到,再从基类里找。按照这个理论,m_data应该可以从基类A< T>里找到。且慢,我们来看看C++Std文档中是怎么说的:
The lookup of names dependent on the template parameters is postponed until the actual
template argument is known
这句话的大意是说“依赖于模板参数的Name Lookup会推迟到模板参数的实际类型确定的时候(也就是模板实例化的时候)”。在上面的程序中,由于m_data依赖于基类A< T>,而基类A< T>又依赖于子类B< T>的模板参数T。因此,在B< T>中定义Test()函数的时候,m_data的lookup会被推迟到A< T>实例化的时候。这时候,就不知道m_data是从哪里来的了。那如何来解决呢?解决的方法就是显式的指明m_data是从哪里来的,具体有下面两种方案:
方案一:
方案二:
[code]template< typename T> class A { protected: int m_data; }; template< typename T> class B : public A< T> { public: void Test(int t) { m_data = t; } }; int main(int argc, char** argv) { B< int> b; b.Test(); }
看完上面这个例子,如果有同学能一眼看出这个例子中存在的问题,那后面的内容可以不用看了,这篇文章中要讲的内容你是清楚的。如果看不出,那我们继续来看这个例子会有什么问题。我们用g++(v4.5.1)来编译上面的例子:
[code]zeshengwu@TengDa_10_12_22_98:~/work/test> g++ test.cc -o test test.cc: In member function 'void B< t>::Test(const T&)': test.cc:18:9: error: 'm_data' was not declared in this scope
神马?m_data没有声明?明明不是在基类A< T>里已经声明了吗?为什么这里编译器会说没有声明呢?难道是编译器有bug?非也非也,g++/gcc是久经考验的工具,它出bug的概率肯定比我们写的程序出bug的概率要小得多,本着任何时候都要先怀疑自已的精神,我们来找寻这里的问题的答案。
我们知道,在普通的继承关系中,Name Lookup的基本顺序是先从子类里找,如果在子类里找不到,再从基类里找。按照这个理论,m_data应该可以从基类A< T>里找到。且慢,我们来看看C++Std文档中是怎么说的:
The lookup of names dependent on the template parameters is postponed until the actual
template argument is known
这句话的大意是说“依赖于模板参数的Name Lookup会推迟到模板参数的实际类型确定的时候(也就是模板实例化的时候)”。在上面的程序中,由于m_data依赖于基类A< T>,而基类A< T>又依赖于子类B< T>的模板参数T。因此,在B< T>中定义Test()函数的时候,m_data的lookup会被推迟到A< T>实例化的时候。这时候,就不知道m_data是从哪里来的了。那如何来解决呢?解决的方法就是显式的指明m_data是从哪里来的,具体有下面两种方案:
方案一:
[code]... void Test(const T& t) { A< T>::m_data = t; } ...
方案二:
[code]... void Test(const T& t) { this->m_data = t; } ...
相关文章推荐
- C语言之strncpy函数原型
- 场景管理:BSP算法C++实现
- C++第五节:重载操作符
- C语言基本知识点
- 场景管理:八叉树算法C++实现
- 场景管理:四叉树算法C++实现
- 黑马程序员--iOS基础知识---C语言中的函数
- 一份C++线程池的代码(转)
- C++类的访问问题
- 控制台下的计算器——C++实现
- 增量式PID算法的C语言代码
- C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别
- C++中的四种cast
- c语言中的函数指针
- 读书笔记MoreEffectiveC++(35)
- C++ 嵌套类使用
- C++ 运算符 优先级
- 读书笔记MoreEffectiveC++(34)
- poj1061青蛙那啥,第一次弄欧几里德,各种问题各种请教
- const放在函数后面