寒星轩

There are innumerable stars in the sky, the smallest is me!

用户操作
[即时聊天] [发私信] [加为好友]
李星ID:starlee
207740次访问,排名341好友65人,关注者107
欢迎大家访问我的Blog。
主要是C++,设计模式,面向对象设计方面的技术文章。
starlee的文章
原创 98 篇
翻译 0 篇
转载 45 篇
评论 331 篇
李星的公告
郑重声明

        本BLOG所发表的 原创文章,作者保留一切权利。必须经过作者本人同意后方可转载,并注名作者(StarLee)和出处(CSDN Blog)。
作者Email:
coolstarlee(at)sohu.com
最近评论
陈诚:好象不一样,我这个共两个类,实现类和接口类
深夜才走在路上:实际上使用CLR封送C++类让人很受伤,在mc中有很多C++的特性不能使用,甚至STL都不可用
hfg :错了错了,当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。

不管基类的析构函数是不是virtual ,派生类的析构函数还是会被调用的,区别只是在于基类的析构函数有没有被调用
Forrest Yu:Star Lee:

如果有两个以上的类需要包装,那又应该怎样做呢?
Forrest Yu:CLR 还是很强大的,
一些老的MFC项目可以先手动添加
#include <afx.h>,
其他的可能要加
#include <windows.h>,
然后再用这种方法.
文章分类
收藏
相册
友情链接
houdy的专栏
lijgame的专栏
lyrebing的专栏
禾青谷
存档
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 C++中一个容易被忽视的名字查找规则收藏

新一篇: 从人物的名字看香港电影人的文化底蕴 | 旧一篇: C++中friend对类封装性的强大破坏性

    现在,有下面的代码:

namespace lx1
{
    
class Point3d
    {
    
public:
        Point3d (
double dx, double dy, double dz)
            : m_dX(dx), m_dY(dy), m_dZ(dz)
        {}

        
double getX() const { return m_dX; };
        
double getY() const { return m_dY; };
        
double getZ() const { return m_dZ; };

    
private:
        
double m_dX;
        
double m_dY;
        
double m_dZ;
    };

    
void TestPoint(const Point3d &pt)
    {
        cout 
<< "Output from lx1::TestPoint()." << endl;
    }
}

namespace lx2
{
    
void TestPoint(const lx1::Point3d &pt)
    {
        cout 
<< "Output from lx2::TestPoint()." << endl;
    }

    
void ShowPoint3d(const lx1::Point3d &pt)
    {
        TestPoint(pt);

        cout 
<< "X: " << pt.getX() << endl;
        cout 
<< "Y: " << pt.getY() << endl;
        cout 
<< "Z: " << pt.getZ() << endl;
    }
}

    你能发现代码中有什么问题吗?
    上面的代码看上去没有什么问题,却不能通过编译,会得到一个“'lx2::TestPoint' : ambiguous call to overloaded function”的错误。也就是说编译器不能确定在ShowPoint3d()函数中调用的是哪个TestPoint()函数。
    也许你会非常不解,为什么会出现这样的编译错误。在命名空间lx2中只有一个函数TestPoint(),为什么编译器会不能确定调用哪个TestPoint()函数呢?虽然在命名空间lx1中有一个跟lx2中参数列表相同的TestPoint()函数,可是在命名空间lx2中并没有用using namespace lx1;这样的语句,编译器应该不会去命名空间lx1中去匹配TestPoint()函数呀。
    事实上,出现编译错误的原因就是在命名空间lx1和lx2里面都有一个函数列表相同的TestPoint()函数。
    在C++中有这样一个名字查找规则--如果在声明函数的参数时使用了一个类,那么在查找匹配的函数名字时,编译器会在包含参数类型的名字空间中也进行查找
    在上面的代码中,命名空间lx2中的TestPoint()函数参数是lx1::Point3d。按照上面的规则,编译器在查找匹配的函数名字时,也会去包含参数Point3d的名字空间(也就是lx1)中进行匹配查找。而在命名空间lx1中也有一个参数列表跟命名空间lx2中一样的TestPoint()函数,所以会出现上面的编译错误。
    这是C++中一条非常容易被忽视的名字查找规则,因此要格外重视。 

发表于 @ 2007年12月10日 09:12:00|评论(loading...)|编辑

新一篇: 从人物的名字看香港电影人的文化底蕴 | 旧一篇: C++中friend对类封装性的强大破坏性

评论

#kahn178 发表于2007-12-10 11:10:53  IP: 116.30.18.*
请问,该怎么运行,我运行之后,还是有问题的,该如何修改呢??
2007-12-10 14:37:50作者回复
文章中已经说明了呀,代码是不能编译通过的。由于C++有文章中的查找规则,所以要想代码编译通过,就不能在lx1和lx2中有名字相同、参数列表也相同的函数TestPoint()。
#fiftymetre 发表于2007-12-11 00:31:16  IP: 221.226.42.*
在C++必知必会 中有名确说明。
#程序员 发表于2007-12-11 09:09:43  IP: 218.108.85.*
这种问题还好意思写进blog.
2007-12-11 09:47:57作者回复
看LS的fiftymetre的回复我才知道,这个问题在《C++必知必会》中有明确说明。虽然我没有看过这本书,但是既然人家能把这个问题写到书里面,我为什么不能写到自己的Blog里面呢?!再说了,Blog本来就是自己的一片天地,写什么都是我自己的自由。另外,这个小知识点并不是人人都知道,我在学习和使用C++的时候发现了这个问题,写出来共享给大家,有什么不好的呢?!
#jssfy 发表于2007-12-11 10:29:41  IP: 202.117.48.*
支持写!
也支持刚推荐的那本书!
#xiaototti 发表于2007-12-11 12:14:58  IP: 121.8.40.*
支持写!
看来光看书还是不行的,要逛逛博客才行啊!
#wei801004 发表于2007-12-11 15:21:21  IP: 211.100.39.*
为什么要写这样的代码,这样的代码写出来本身就是垃圾。
晦涩!!!!!
2007-12-11 16:39:50作者回复
写这样的代码是为了说明C++中的这个名字查找规则。任何高手都是从初学者成长起来的。谁没有在初学C++的时候犯过低级错误?!你能保证你从来没有写过“垃圾”代码?!
2007-12-11 16:41:56作者回复
其实,人无完人,就连大师、高手也会犯非常低级的错误!详情请看《大师也犯低级错误--《CODE COMPLETE (Second Edition)》中的2处代码错误》(http://blog.csdn.net/starlee/archive/2007/08/09/1733132.aspx)。
#manan_ycb 发表于2007-12-14 15:18:55  IP: 218.24.136.*
个人认为,编译器能够检查出来的错误不用“格外重视”,都检查出来了,改了就是
2007-12-14 17:03:24作者回复
编译器能够检查出来的错误并不代表这个错误很容易修改。如果不知道这个规则,很难知道错误在什么地方。文章中的例子是命名空间lx1和lx2在一起,如果这两个命名空间不在同一个文件中,那么不知道这个规则的话,将非常难发现问题出在什么地方。
#lishiyong110 发表于2007-12-15 00:32:10  IP: 58.49.251.*
很不错的 很多初学者应该都不知道的 我就是 呵呵 copy下来
#wanfustudio 发表于2007-12-19 16:18:44  IP: 218.94.6.*
我竟然编译通过了
#cqzhangdali 发表于2008-01-27 20:15:54  IP: 211.158.38.*
我不知道有个规则..感谢
#guogangj 发表于2008-01-28 16:13:54  IP: 61.172.24.*
不知道为什么要有这么条规则。确实看起来很奇怪。

更奇怪的是我也编译通过了:Microsft VC++ 6.0/Windows XP SP2。
2008-01-29 08:48:33作者回复
呵呵~~现在还在用VC++6.0呀。VC++6.0和C++标准几乎同时出台(1998年),VC++6.0对C++标准的支持可想而知。你用新版本的VC++试试。另外,C++标准也在不断更新;当然,VC++也会不断更新。
#ks_gq 发表于2008-02-20 14:33:35  IP: 219.131.196.*
支持楼主, 不用理会别人的评价
#maliang1225 发表于2008-02-23 00:01:32  IP: 124.78.46.*
支持楼主,这也是知识的一种传播!
#commemorate 发表于2008-08-26 18:52:55  IP: 220.169.30.*
学东西的时候,我们应该专,但是不应该专到楼主这种程度。
2008-08-26 20:22:21作者回复
呵呵~~
你觉得太专了,可是我并不觉得很专。
开发做的时间长了,什么怪诞的问题都有可能碰上。
#linandixon 发表于2008-08-26 23:37:14  IP: 117.32.202.*
文章不错,我不是什么高手,也还没去看过《C++必知必会》,这很好,你们讨论的东西也不错!!
发表评论  


登录
Csdn Blog version 3.1a
Copyright © 李星