免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6123 | 回复: 5
打印 上一主题 下一主题

[C++] 模板类继承 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-09 11:21 |只看该作者 |倒序浏览
本帖最后由 chllcy88 于 2013-10-09 11:23 编辑
  1. template<class TTable, class TGTP>
  2. class CCmQry
  3. {
  4. public:
  5.         CCmQry(const char* szField, TGTP* pGTP)
  6.                 : m_pGTP(pGTP)
  7.         {

  8.         }

  9.         int is_empty(TTable* p)
  10.         {
  11.                 return false;
  12.         }

  13.         template<class TKey>
  14.         void query_table(TKey key)
  15.         {

  16.         }

  17. public:
  18.         char m_szField[64];
  19.         TGTP* m_pGTP;
  20. };

  21. template<class TTable, class TGTP, class TSubQry>
  22. class CCmQryParent : public CCmQry<TTable, TGTP>
  23. {
  24.     //typedef CCmQry< TTable,  TGTP> Base;
  25. public:
  26.         CCmQryParent(const char* szField, TGTP* pGTP, TSubQry* pSubQry)
  27.                 : CCmQry<TTable, TGTP>(szField, pGTP)
  28.                 , m_pSubQry(pSubQry)
  29.         {
  30.         }

  31.         template<class TKey>
  32.         void query_table(TKey key)
  33.         {
  34.         //Base::m_szField[10] = 0;
  35.         m_szField[10] = 0;
  36.         }

  37. public:
  38.         TSubQry* m_pSubQry;
  39. };


  40. int main()
  41. {
  42.     return 0;
  43. }
复制代码
  1. template<class TTable, class TGTP>
  2. class CCmQry
  3. {
  4. public:
  5.         CCmQry(const char* szField, TGTP* pGTP)
  6.                 : m_pGTP(pGTP)
  7.         {

  8.         }

  9.         int is_empty(TTable* p)
  10.         {
  11.                 return false;
  12.         }

  13.         template<class TKey>
  14.         void query_table(TKey key)
  15.         {

  16.         }

  17. public:
  18.         char m_szField[64];
  19.         TGTP* m_pGTP;
  20. };

  21. template<class TTable, class TGTP, class TSubQry>
  22. class CCmQryParent : public CCmQry<TTable, TGTP>
  23. {
  24.     typedef CCmQry< TTable,  TGTP> Base;
  25. public:
  26.         CCmQryParent(const char* szField, TGTP* pGTP, TSubQry* pSubQry)
  27.                 : CCmQry<TTable, TGTP>(szField, pGTP)
  28.                 , m_pSubQry(pSubQry)
  29.         {
  30.         }

  31.         template<class TKey>
  32.         void query_table(TKey key)
  33.         {
  34.         Base::m_szField[10] = 0;
  35.         }

  36. public:
  37.         TSubQry* m_pSubQry;
  38. };


  39. int main()
  40. {
  41.     return 0;
  42. }
复制代码
第一段代码编译报错
test.cpp: In member function 'void CCmQryParent<TTable, TGTP, TSubQry>::query_table(TKey)':
test.cpp:42: error: 'm_szField' was not declared in this scope
第二段代码就可以,不知道是为什么?
既然已经是public继承了,那就应该可以直接使用啊?请指点下

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
2 [报告]
发表于 2013-10-09 12:34 |只看该作者
CCmQry<TTable, TGTP>::m_szField[10] = 0;

论坛徽章:
0
3 [报告]
发表于 2013-10-09 12:39 |只看该作者
回复 2# bruceteen


    请帮忙解释下呢,为什么要这样?或者给个关键词 我baidu下

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
4 [报告]
发表于 2013-10-09 12:50 |只看该作者
chllcy88 发表于 2013-10-09 12:39
回复 2# bruceteen
请帮忙解释下呢,为什么要这样?或者给个关键词 我baidu下

你得找 幻之上帝、myworkstation 等大侠。
我只知道模板不去外面找,所以写成 m_szField[10] = 0; 肯定报错,因为它不认识 m_szField 是什么东西。
你写成 CCmQry<TTable, TGTP>::m_szField[10] = 0; 的话编译器就认为它是CCmQry<TTable, TGTP>中的一个成员,即使 CCmQry<TTable, TGTP> 中没有
m_szField 这个玩意儿。
你写成 typename CCmQry<TTable, TGTP>::m_szField a = 0; 的话编译器就认为它是CCmQry<TTable, TGTP>中的一个类型,即使 CCmQry<TTable, TGTP> 中没有 m_szField 这个玩意儿。
你说什么模板就认为是什么,直到实例化时进行另一个层次上的语法检查。

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
5 [报告]
发表于 2013-10-09 18:11 |只看该作者
回复 3# chllcy88


这个问题实质上就是模板的两阶段名称查找two-phase name lookup.

两阶段查找:
第1阶段:发生在模板的解析阶段
非依赖型名称:普通查找+ADL
非受限的依赖型名称:普通查找,但它的查找是不完整的,在实例化的时候,还会再次进行查找。

第2阶段:发生在模板的实例化阶段,此时发生的地点称为一个实例化点POI
依赖受限名称:普通查找+ADL
非受限的依赖型名称:ADL (查询完后,和第1阶段的查找结果合并成为候选函数集合)

m_szField是个类型依赖的受限名称,不能编译的代码中m_szField写的方式使编译不认为m_szField是个受限名称,所以找不到这个名称,有两个办法解决这个问题,使用第二段代码中的Base::m_szField或者this->m_szField,不能编译的代码在VC++中应该是可以编译过的,因为VC++不严格遵循C++标准的规定,把名称查找都放到了第二阶段,实际上就是隐式的使用this->m_szField。gcc和llvm严格遵循C++规定,所以应试都编译不过第一段代码。

最后强调一点:使用this是个好习惯。:wink:

论坛徽章:
0
6 [报告]
发表于 2013-10-10 10:41 |只看该作者
多谢楼上版主的指点
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP