BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #28419同步于 2009/9/12
CPP机器人发帖

[合集] 【已解决】问个私有继承带来的问题

shenlei
2009/9/12镜像同步0 回复
☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 19:58:16 2009) 提到: class BaseC//基类 { public: BaseC(void){} virtual void show(); virtual ~BaseC(void){} }; void BaseC::show() { cout<<"BaseC::show()"<<endl; } class Parent:private BaseC//私有继承基类 { private: virtual void show() { std::cout<<"Parent::show()"<<std::endl; }; public: Parent(void); ~Parent(void); }; int _tmain(int argc, _TCHAR* argv[]) { BaseC s1; s1.show(); Parent p1; // p1.show();//无法访问私有成员 BaseC &s2=(BaseC &)p1; s2.show();//结果是什么啊? return 0; } 程序运行结果: BaseC::show() Parent::show() 请按任意键继续. . . 为什么会这样呢? 本来不能访问自己的私有成员变量的,这里结果私有继承导致间接访问自己的私有成员了啊? ☆─────────────────────────────────────☆ DDB (Flétriescoeur) 于 (Thu Apr 2 20:00:50 2009) 提到: 哇,帮顶 p1.show();//无法访问私有成员 因为p1的show是private的。不能被他的对象访问 第二个嘛,好好看看多态到底是怎么回事就会明白了 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:01:19 2009) 提到: 【 在 DDB 的大作中提到: 】 : 哇,帮顶 呵呵 ddb很闲啊 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:01:55 2009) 提到: 【 在 DDB 的大作中提到: 】 : 哇,帮顶 大牛给我解释解释 ☆─────────────────────────────────────☆ DarkIce ( ) 于 (Thu Apr 2 20:05:37 2009) 提到: 编译的时候判断有可以用的虚函数,所以编译通过了 运行的时候不再进行权限判断,动态加载了子类的函数调用 【 在 fox1987 (王子的狐狸§邪恶VS天真) 的大作中提到: 】 : class BaseC//基类 : { : public: : ................... ☆─────────────────────────────────────☆ DDB (Flétriescoeur) 于 (Thu Apr 2 20:06:34 2009) 提到: 【 在 fox1987 的大作中提到: 】 : 呵呵 : ddb很闲啊 看1楼 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:09:25 2009) 提到: 【 在 DarkIce 的大作中提到: 】 : 编译的时候判断有可以用的虚函数,所以编译通过了 : 运行的时候不再进行权限判断,动态加载了子类的函数调用 这个是怎么个调用的情况呢 为什么调出来了派生类的私有函数了呢 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:10:14 2009) 提到: 【 在 DDB 的大作中提到: 】 : 看1楼 你的解释对我没用 我那里那么注释就是说直接类是不能访问私有成员的 ☆─────────────────────────────────────☆ Jarod (学五608鬼魂) 于 (Thu Apr 2 20:10:41 2009) 提到: 一堆的语法滥用,最后得了一个奇怪的现象还希望得到解释。。。。。 虽然我不懂这咋回事,但真正的程序不会这样写的。。。。。。。 【 在 fox1987 的大作中提到: 】 : class BaseC//基类 : { : public: : ................... ☆─────────────────────────────────────☆ DarkIce ( ) 于 (Thu Apr 2 20:11:59 2009) 提到: 运行的时候又不判断是私有还是共有的,直接动态调用虚函数就是了 对私有还是共有的权限判断是在编译完成的,但是编译的时候因为基类是public的,所以存在可以调用的函数,编译可以通过 【 在 fox1987 (王子的狐狸§邪恶VS天真) 的大作中提到: 】 : 这个是怎么个调用的情况呢 : 为什么调出来了派生类的私有函数了呢 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:13:17 2009) 提到: 【 在 DarkIce 的大作中提到: 】 : 运行的时候又不判断是私有还是共有的,直接动态调用虚函数就是了 : 对私有还是共有的权限判断是在编译完成的,但是编译的时候因为基类是public的,所以存在可以调用的函数,编译可以通过 哦 差不多吧 基本可以接受 我在慢慢消化消化。。 ps:darkice目前在哪里高就啊? ☆─────────────────────────────────────☆ DarkIce ( ) 于 (Thu Apr 2 20:13:59 2009) 提到: 小公司 【 在 fox1987 (王子的狐狸§邪恶VS天真) 的大作中提到: 】 : 哦 : 差不多吧 : 基本可以接受 : ................... ☆─────────────────────────────────────☆ Jarod (学五608鬼魂) 于 (Thu Apr 2 20:15:24 2009) 提到: 喔。这样解释通了。 public/private这些权限是静态检查的。 使用vtable与这静态的没关系了。 话说,Java好像权限检查会带到运行时中。所谓的“java更安全”的体现之一 【 在 DarkIce 的大作中提到: 】 : 运行的时候又不判断是私有还是共有的,直接动态调用虚函数就是了 : 对私有还是共有的权限判断是在编译完成的,但是编译的时候因为基类是public的,所以存在可以调用的函数,编译可以通过 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:17:49 2009) 提到: 嗯 暂时这么理解吧 感觉对编译检查 运行检查还是搞不很清楚啊 不过谢谢darkice的解释 ☆─────────────────────────────────────☆ DarkIce ( ) 于 (Thu Apr 2 20:20:02 2009) 提到: 前段时间看(More) Effective c++时候看到过这种问题 【 在 fox1987 (王子的狐狸§邪恶VS天真) 的大作中提到: 】 : 嗯 : 暂时这么理解吧 : 感觉对编译检查 运行检查还是搞不很清楚啊 : ................... ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:20:53 2009) 提到: 【 在 DarkIce 的大作中提到: 】 : 前段时间看(More) Effective c++时候看到过这种问题 看来还得继续好好看书啊 好多书要看啊 ☆─────────────────────────────────────☆ DDB (Flétriescoeur) 于 (Thu Apr 2 20:23:07 2009) 提到: 【 在 fox1987 的大作中提到: 】 : 你的解释对我没用 : 我那里那么注释就是说直接类是不能访问私有成员的 那只能理解成s2是父类指针,父类的show是public的,再由于多态,结果调到子类的show了。 虽然声明为private的函数不能直接访问,但是如果将private的函数的函数地址传出来,还是可以访问的,这里就是这个原因。 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:31:10 2009) 提到: 【 在 DDB 的大作中提到: 】 : 那只能理解成s2是父类指针,父类的show是public的,再由于多态,结果调到子类的show了。 : 虽然声明为private的函数不能直接访问,但是如果将private的函数的函数地址传出来,还是可以访问的,这里就是这个原因。 哇 。。 好厉害啊 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 20:40:55 2009) 提到: 【 在 DDB 的大作中提到: 】 : 那只能理解成s2是父类指针,父类的show是public的,再由于多态,结果调到子类的show了。 : 虽然声明为private的函数不能直接访问,但是如果将private的函数的函数地址传出来,还是可以访问的,这里就是这个原因。 现在在哪? 公司? ☆─────────────────────────────────────☆ DDB (Flétriescoeur) 于 (Thu Apr 2 20:54:50 2009) 提到: 【 在 fox1987 的大作中提到: 】 : 现在在哪? : 公司? 加班,我XXXXXX ☆─────────────────────────────────────☆ DarkIce ( ) 于 (Thu Apr 2 20:55:15 2009) 提到: 淡定 【 在 DDB (Flétriescoeur) 的大作中提到: 】 : 加班,我XXXXXX ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Thu Apr 2 21:21:39 2009) 提到: 【 在 DDB 的大作中提到: 】 : 加班,我XXXXXX 加班好啊 加班费刚刚的啊 ☆─────────────────────────────────────☆ AHbupt (Peter喜欢Caroline) 于 (Thu Apr 2 21:36:48 2009) 提到: 【 在 DarkIce 的大作中提到: 】 : 运行的时候又不判断是私有还是共有的,直接动态调用虚函数就是了 : 对私有还是共有的权限判断是在编译完成的,但是编译的时候因为基类是public的,所以存在可以调用的函数,编译可以通过 还是这个解释好哇 ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:41:46 2009) 提到: 我来回答一下: 因为你采用了传引用调用,所以两个引用引用了同一个地址空间,而在c++中private 和public只是表明了对于这个方法是否暴露其端口地址,由于后一个类是继承自前一个类的,所以在使用引用之后编译器会把其相似的部分相对应的对应起来,也就是会把Parent的show和BaseC中的show的地址对应起来,即BaseC中的show是public的访问方式但是是Parent中的show的地址! ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:42:52 2009) 提到: 也可以构建一个与Parent相似的类,再用传引用强制转换也能达到同样的效果! 因为c++编译器只会对地址和名字进行解析与对应,一旦名字和顺序不对就会导致解析失败....如下有两个例子: ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:43:55 2009) 提到: ------------------Class.h-------------------- #include "stdafx.h" using namespace std; class BaseC { public: BaseC(void){} virtual void show(); virtual ~BaseC(void){} }; void BaseC::show() { cout<<"BaseC::show()"<<endl; } class Parent { private: int a; virtual void go() { cout<<"go"<<endl; } virtual void show() { std::cout<<"Parent::show()"<<std::endl; } public: Parent(void){} ~Parent(void){} }; ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:45:03 2009) 提到: #include "stdafx.h" #include "Class.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { BaseC s1; s1.show(); Parent p1; // p1.show();//无法访问私有成员 BaseC &s2=(BaseC &)p1; s2.show();//结果是什么啊? return 0; } 这样调用就会失败!但是例2: ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:56:04 2009) 提到: #include "stdafx.h" using namespace std; class BaseC { int a; public: virtual void show() { cout<<"BaseC::show()"<<endl; } BaseC(){} }; class Parent { int a; private: virtual void show() { std::cout<<"Parent::show()"<<std::endl; } public: Parent(){} }; ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 09:58:24 2009) 提到: 改为以上代码后就可以访问了!但是这样的问题只会出现在虚函数中,因为只有虚函数才需要分配地址!大家可以试试,一起学习! ☆─────────────────────────────────────☆ visualbupt (思齐) 于 (Fri Apr 3 10:08:14 2009) 提到: 【 在 dafei 的大作中提到: 】 : 改为以上代码后就可以访问了!但是这样的问题只会出现在虚函数中,因为只有虚函数才需要分配地址!大家可以试试,一起学习! 虚函数始终是虚函数....... ☆─────────────────────────────────────☆ dafei (嘿嘿大飞) 于 (Fri Apr 3 10:09:09 2009) 提到: 再解释一下吧,其实就是对隐藏成员虚函数表地址赋值了! ☆─────────────────────────────────────☆ visualbupt (思齐) 于 (Fri Apr 3 10:09:48 2009) 提到: 【 在 dafei 的大作中提到: 】 : 再解释一下吧,其实就是对隐藏成员虚函数表地址赋值了! 真的,虚函数就是虚函数,加virtual和不加是一样一样的...
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。