浏览 4197 次
锁定老帖子 主题:奇怪的方法调用居然可以执行
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-03-30
代码如下: class Base { public: virtual void processCommon(){} }; class Sub1: public Base { }; class Sub2: public Base { public: void processOnlyInSub2() { printf("Sub2.processOnlyInSub2 ...\n"); } }; 主函数为: #include "stdafx.h" #include "base.h" using namespace std; int main() { Sub1* sub1Pointer = new Sub1(); Sub2* sub2Pointer = dynamic_cast<Sub2*>(sub1Pointer); sub2Pointer->processOnlyInSub2(); return 0; } 因为一直用java而接触C++比较少,所以比较奇怪 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-03-30
这样都是可以的
int addr=0x1234; sub2*p=(sub2*)addr; p->processOnlyInSub2(); 再看这里 void processOnlyInSub2() 这句编译后就是这样子 void processOnlyInSub2(Sub2*this); 而这句 sub2Pointer->processOnlyInSub2(); 相当于 processOnlyInSub2(sub2Pointer); |
|
返回顶楼 | |
发表时间:2007-03-30
发现原因了,原来sub2Pointer的值为空也可以调用,不象java那样会抛空指针异常
C++确实没有Java安全和不易出错 |
|
返回顶楼 | |
发表时间:2007-03-30
的确不如Java安全,
不过这个方法跟对象的状态无关,如果访问成员就会异常了。 有一些惯用法是基于这个特性的。 在实践中都是没遇到过因为他不应该正常但却正常了而导致不正常。 |
|
返回顶楼 | |
发表时间:2007-03-31
simohayha 写道 而这句
sub2Pointer->processOnlyInSub2(); 相当于 processOnlyInSub2(sub2Pointer); 嗯,明白了,感谢指点 我又做了两个实验,一个是定义全局函数void processOnlyInSub2(Sub2*); 结果并没有和类Sub2的调用sub2Pointer->processOnlyInSub2() 产生冲突,所以Sub2的调用虽然编译成processOnlyInSub2(sub2Pointer),但是应该是做了名称(或空间)的特殊除了吧? 第二个是,如果我在父类中也定义一个多态的函数virtual void processOnlyInSub2(),然后子类Sub2再重定义,这样之后象上面那种调用就抛错了 |
|
返回顶楼 | |
发表时间:2007-04-04
关键还是C++中class的实现,所有Class的成员函数隐藏一个参数,也就是this指针,simohayha说得就是这个意思
|
|
返回顶楼 | |
发表时间:2007-04-04
virtual的函数就不一样了,这部分函数是放在vtbl中的,所以需要去找,没有的话就会错误的.
同样你所写的例子,如果函数中用到了class的成员变量也会异常的! |
|
返回顶楼 | |
发表时间:2007-04-04
qinysong 写道 simohayha 写道 而这句
sub2Pointer->processOnlyInSub2(); 相当于 processOnlyInSub2(sub2Pointer); 嗯,明白了,感谢指点 我又做了两个实验,一个是定义全局函数void processOnlyInSub2(Sub2*); 结果并没有和类Sub2的调用sub2Pointer->processOnlyInSub2() 产生冲突,所以Sub2的调用虽然编译成processOnlyInSub2(sub2Pointer),但是应该是做了名称(或空间)的特殊除了吧? 严格说,sub2Pointer->processOnlyInSub2(); 并不等于 processOnlyInSub2(sub2Pointer); C++ 编译器 有 "命名粉碎" 机制, sub2Pointer->processOnlyInSub2(); 大概 产生 类似 于 _ZN4Sub2******(Sub2*) 这样的一个 函数. 嗯,这时候,估计你会想那 弄个 _ZN4Sub2******(Sub2*)这样 名字的函数,看 编译器 怎么办, 编译器 会再次 sub2Pointer->processOnlyInSub2();产生一个其他的名字. 以此类推,总会 产生其他其他的名字.到底 啥 时候 是个头呢, 这要看编译器具体实现了. 记得似乎是 Matthew Wilson 说过, 故意 和 编译器 过不去 会不得好死. 所以别玩的太过火了. |
|
返回顶楼 | |
发表时间:2007-04-04
这个问题在C++圈子论坛里讨论过的,可以去翻翻。
|
|
返回顶楼 | |