
试验代码如下
class CHello { public: CHello() { this.SayHello(); } virtual ~CHello(); virtual void SayHello() { printf("hello"); } }; class CHelloA : public CHello { publi: CHelloA(); ~CHelloA(); void SayHello() { printf("hello a"); } }; void main() { CHelloA a; } 猜猜输出什么?
1 sbabybird OP 同样的思路,在 java 和 python 下输出是正常的,即子类的 SayHell 被调用。 |
2 sbabybird OP 在 vs2015 下编译的,输出显示调用的是父类的 SayHello。 |
3 nyanyh 2017-05-03 13:31:18 +08:00 |
4 vingz 2017-05-03 13:32:41 +08:00 Hello? |
5 limhiaoing 2017-05-03 13:32:50 +08:00 via iPhone 这代码能编译通过? |
6 wevsty 2017-05-03 13:34:41 +08:00 1、楼主的代码编译都过不了 this 是指针,指针类型不能用.来调用 CHelloA,~CHelloA,~CHello 都只有声明没有定义,link 的时候会 error 的 2、如果正确修改代码 那么最后应该是输出 hello 而不是 hello a |
7 solaya 2017-05-03 13:36:15 +08:00 这代码 你跑过???去看看 effective c++ |
8 wangxn 2017-05-03 13:38:25 +08:00 不要在构造函数和析构函数中调用虚函数,不是一个常识吗?楼主真是大惊小怪啊…… |
9 vingz 2017-05-03 13:40:24 +08:00 java 下,如果 sayHello 是 private 权限,父类的函数被调用,如果是其他权限(测试了 default,protected )子类的函数被调用。 |
10 sbabybird OP 不好意思,那个点写错了,应该是 this->SayHello();我是凭记忆打的,确实在 vs 下运行过。 @solaya |
11 wangxn 2017-05-03 13:43:52 +08:00 Python 之所以能在构造函数中调用到子类中的同名函数,原因在于 Python 压根没有虚函数这个概念,所谓调用只是 self 对象在它自己的 __dict__ 中进行名字查找而已。 |
14 limhiaoing div class="badges"> 2017-05-03 13:48:47 +08:00 via iPhone @sbabybird 想探讨原因就不应该用这种标题! |
15 wevsty 2017-05-03 13:57:23 +08:00 @sbabybird 对 C++来说 virtual 函数是在类对象里面有虚表来确定执行哪个函数的,但是继承过来的对象不修改基类中的虚表,而是附加新的。 继承并不是单纯的按照基类复制成一个新的类,这里是依赖关系所以仍然会保持基类里原有的行为,在基类中实现构造的时候就确定下来的行为是不会改变的。 |
16 sbabybird OP @limhiaoing 抱歉了哈,确实有些随意了,感谢指正 |
17 huyan3280 2017-05-03 14:43:15 +08:00 hello |
18 7wN5407klUw768m0 2017-05-03 16:08:19 +08:00 去看《深度探索 C++对象模型》 |
19 Pyjamas 2017-05-03 16:09:15 +08:00 上面+1 |
20 geelaw 2017-05-03 16:11:36 +08:00 via iPhone 对象的身份(具体度)是逐渐升级的。 这也是为什么会有“调用过了纯虚函数”这种错误,在基类的构造函数里面调用纯虚函数会失败。 析构的时候对象身份逐渐降级。 |
21 visionsmile 2017-05-10 23:46:37 +08:00 via Android 楼主了解下 C++类的构造顺序就明白了。 |
22 Frost 2017-06-06 10:02:16 +08:00 effective C++里面提到过,同样的状况会出现在基类引用或指针调用基类虚函数的默认参数里,它只会认基类那个虚函数的默认参数。 |