两段想当然写下的代码,你看出问题了吧
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 清源游民 阅读(1495) 评论(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了,向你致敬!  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

留言簿(35)

随笔分类(78)

随笔档案(74)

文章档案(5)

搜索

  •  

最新评论

阅读排行榜

评论排行榜