这几天学习c++的总结-->c++论坛第一帖
程序代码:
#include <iostream> using namespace std; class Father { public: void eat() { cout<<"父亲喜欢吃米饭"<<endl; } void smoking() { cout<<"喜欢抽烟"<<endl; } private: int weight; int age; }; class Son :public Father { public: void eat() { cout<<"儿子喜欢吃粉"<<endl; } }; int main() { Son s; s.eat(); return 0; } 输去: 儿子喜欢吃粉 这里只是输去子类eat 而父亲的eat 到哪里去了呢! 父亲的子类被儿子的隐藏了。你可以把 s.eat(); 换成 s.Faher::eat();显示调用父类的eat; 就算你你把子类的eat() 换成 eat(int); 然后在 int main() { Son s; s.Father::eat(1); s.eat(); return 0; } 会发生编译错误。 说你s.eat() 不能添加参数. 说明你不能调用父类的eat 你改成s.Father::eat(); 就可以了。 这就是隐藏了。 ----------------------------------------------------------- 父类 和子类的内存模型 父类: 父类 子类: 父类 + 子类外加部分 他们首地址是一样的。 可以通过 #include <iostream> using namespace std; class Father { public: void eat() { cout<<"父亲爱吃米饭"<<endl; } void show() { cout<<"父亲内存地址:"<<this<<endl; } }; class Son:public Father { public: void eat() { cout<<"儿子爱吃粉"<<endl; } void show1() { cout<<"儿子内存地址:"<<this<<endl; } }; int main() { Son s; s.show1(); s.show(); return 0; } 儿子内存地址:0012FF7C 父亲内存地址:0012FF7C Press any key to continue 如果你把Main 改成下面 int main() { Son s; Father *pF; pF = &s; pF->eat(); return 0; } 输去结果会是下面 父亲爱吃米饭 Press any key to continue 为什么会这样呢!! 把一个子类地址传递给父类指针可以调用成功呢! 我来说明一下: 1: 静态绑定 和run-time(运行)绑定。 静态绑定:在编译的时候就确定好了关系, 确定好了你要调用哪个函数, 就像c 语言中的数组大小是在编译的时候就确定 ,是不能够动态改变大小的。 静态编译是通过你的数据类型来来确定的,就像sizeof() 来判断大小是根据你定义的数据类型来判断你的大小。如果你强制转换把一个类型转换另一个类型的时候,可以骗过编译器但你运行的时候就会报错。 动态编译: 根据你给他对象的类型来确定的。。。 2:这里就要用用到子类和父类的首地址一样。 可以说父类的前面部分和子类的部分相同 你真好用的父类指针 所以偏移量是一样的 所以这样才会真好调用父类eat(); 这里指针不一样偏移量是不一样的。。 int main() { Son s; Father f; Son *pS = (Son *)&f; pS->eat(); return 0; } 也可以通过这个上面的函数反正明那个事实