c++,要细心不能想当然

两段想当然写下的代码,你看出问题了吧
1  class  Data;
2  Data *  FindData();
3  void  GetData(Data *  dataPtr)
4  {
5      dataPtr = FindData();
6  }
7  Data *  data = NULL;
8  GetData(data);
9  data -> somefunction();
第二段代码,更得仔细点
 1  class  A;
 2  class  B;
 3  const   *  GetA();
 4  const   *  GetB();
 5  template < typename T >
 6  int  GetSpecialValue(T *  classPtr)
 7  {
 8      return    3721 ;
 9  }
10 
11  template <>
12  int  GetSpecialValue <> (A *  classPtr)
13  {
14      return    37 ;
15  }
16  template <>
17  int  GetSpecialValue <> (B *  classPtr)
18  {
19      return   21 ;
20  }
21  const   *  classPtr = GetA();
22  int  ret = GetSpecialValue(classPtr);
23  cout << ret << endl;  // out 3721! why not 37?
24 
25 
26 
第一段的问题在于看到指针想当然认为是地址,data 可以带回反回值,其实因为这里是值传递,实参data把自己的值赋给了dataPtr,dataPtr后来确实从FindData()得到了想要的值,但这对一点影响也没有,所以函数返回时,data的值没有发生变化,也就是没有带回想要的值。
只要不想当然,仔细一想就明白了,解决办法很简单:
1    void  GetData(Data *&  dataPtr)
2  4  {
3  5      dataPtr = FindData();
4  6  }
第二段的问题是没有注意到那个const, T*  和 T const* 是不一样的,不能完全匹配,所以不会找到对A类型的特化版本,解决办法可以这样:
 1  template < typename T >
 2  int  GetSpecialValue(T  const *  classPtr)
 3  {
 4      return    3721 ;
 5  }
 6 
 7  template <>
 8  int  GetSpecialValue <> (A  const *  classPtr)
 9  {
10      return    37 ;
11  }
12  template <>
13  int  GetSpecialValue <> (B  const *  classPtr)
14  {
15      return   21 ;
16  }
能过这两个小例子就可以知道,C++细节很多,要仔细,不能想当然。
posted on 2009-05-06 21:09 清源游民 阅读(353) 评论(5)   编辑  收藏 引用 所属分类: C++


FeedBack:
#  re: c++,要细心不能想当然
2009-05-06 22:15 | Sunshine Alike
恍然小悟,谢了 :)   回复   更多评论
  
#  re: c++,要细心不能想当然
2009-05-20 20:52 | 闫军yy
!!!   回复   更多评论
  
#  re: c++,要细心不能想当然
2009-06-01 13:05 | peng
您好:
我用第一段代码做了一个测试,好象可以呀?
#include <stdio>
class Data{
public:
void somefunction(){printf("bbb/n");}
};
Data asd=Data();
Data* FindData() {
// return new Data(); //用这句也行
return &asd;
}

void GetData(Data* dataPtr) { dataPtr=FindData(); }

int main(int argc, char* argv[])
{
printf("aaa/n");
Data* data=NULL;
GetData(data);
data->somefunction();
return 0;
}

程序运行并打印出
aaa
bbb   回复   更多评论
  
#  re: c++,要细心不能想当然
2009-06-01 16:18 | 清源游民
@peng
你的这个测试其实引出了,c++的一个更深入的问题:c++对象模型。
在你的程序中,当执行GetData(data)后,你认为data已经有值了,非NULL,
要不怎么会没报错,而且打印了‘正确’结果,其实如果这样写你的测试代码
Data* data=NULL;
//注意:你的原来那行注释掉 GetData(data);
data->somefunction();
一样会打印出结果:bbb,没有报错
你可能会怀疑:data=NULL????
没错,这就是c++对象模型问题了。编译器会把data->somefunction()这行代码改成类似这样:
sonefunction(data),data就是this指针。因为somefunction()函数里没有用到this指针,他为null,也无所谓。所以会打印出“bbb".

真的,c++要细心,不能想当然,呵呵。

   回复   更多评论
  
#  re: c++,要细心不能想当然
2009-12-03 16:38 | joewan
@清源游民
这个点评真精彩!
虽然我对c++类型模型知道一些,以及mangling机制;
只是对这个
Data* data=NULL;
data->somefunction();
能打印出结果来颇感意外,NULL指针竟然也能解引用!

我也是从其他朋友blog,知道你,订阅你的blog了,向你致敬!   回复   更多评论
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值