1.(1)派生类和基类的成员函数同名的处理
#include<iostream> #include<string> using namespace std; class A { private: int a; public: A(int x) { a = x; } void setA(int x) { a = x; } void show() { cout << "基类A=" << a << endl; } }; class C :public A { //公有继承 A private: int c; public: C(int a, int b, int c1) :A(a) { c = c1; } //派生类构造函数 void setC(int x, int y) { c = x; } void showC() { cout << "c=" << c << endl; } /*void show() { cout << "派生类C=" << c << endl; }*/ void show() { A::show(); cout << "派生类C=" << c << endl; } }; void main() { A ta(12); C tc(1, 2, 3); ta.show(); tc.show(); }
▲main函数中的ta.show() 和tc.show()分别调用的哪个类中的show函数?
答:ta.show()调用基类中的show函数,tc.show()调用派生类中的show函数。
▲将C类中的show函数修改为:
void show() {
A::show();
cout<<"派生类C="<<c<<endl;
}
将main函数中的ta.show()语句注释掉,运行观察输出结果。
①子类中存在和基类中同名同参的函数,这时候基类的函数会被子类的函数覆盖,直接用子类对象调用同名函数会默认调用子类的函数。
②当子类中的函数与基类的函数,函数名相同,形参的个数或类型不同时,不能直接用子类对象调用(直接调用编译也会提示错误)。
此时要从子类中访问基类的函数有两种方法:
1、定义基类指针,让基类指针指向派生类对象,用指针调用基类函数。
2、显示调用基类函数,既在基类函数之前加上基类名和域说明符。
(2)赋值兼容原则
#include<iostream> #include<string> using namespace std; class A { private: int a; public: A(int x) { a=x; } void setA(int x){ a = x; } void show(){ cout<<"基类A="<<a<<endl; } }; class C:public A { //公有继承A private: int c; public: C(int a,int c1):A(a) { c=c1; } //派生类构造函数 void setC(int x) { c = x; } void showC() { cout<<"c="<<c<<endl; } void show() { //A::show(); cout<<"派生类C="<<c<<endl; } }; void main() { A ta(12),*pa; C tc(1,3); A &ya=tc; //赋值兼容原则 pa=&tc; cout<<"pa-show"<<endl; pa->show(); //输出什么结果 cout<<"ya.show"<<endl; ya.show(); //输出什么结果 ta=tc; cout<<"ta.show"<<endl; ta.show(); //输出什么结果 }
派生类对象的地址 否可以赋值给基类的指针变量?派生类对象是否可以赋值给基类的引用对象和基类对象本身?
答:都可以。
赋值兼容规则:派生类的对象可以赋值给基类的对象;派生类对象可以初始化基类的引用; 派生类的对象地址可以赋值给指向基类的指针。
2) 预测输出结果,然后运行,说明main函数中的三个show函数分别调用的是哪个类中的show成员函数。
答:预测 基类A=1 基类A=1 基类A=1
调用的都是基类的show函数。
3)将类A中的show函数改为虚函数:virtual void show() { cout<<"基类A="<<a<<endl;}
其他地方不变。
运行程序,观察输出结果,说明:在main函数中,通过基类的哪些形式可以访问派生类的同名虚函数?在main函数中的哪条语句说明了不通过这样的形式,就只能访问基类的同名函数。
答:1、通过基类访问派生类的同名虚函数:①定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。②通过替代基类对象向基类对象的的引用进行复制或初始化。
2、ta=tc
练习:编程实现
定义基类Base,其功能是计算图形的面积,它只有一个公有的成员虚函数area。从Base类公有派生三角形类Triangle和圆类Circle,在类Triangle和类Circle中,分别定义自己的area函数,用于计算各自的面积。在main函数中,声明Base类的对象指针变量,分别指向类Triangle和类Circle的对象,通过指针调用area函数显示相应对象的面积。(用虚函数实现多态)
#include<iostream> using namespace std; const float PI = 3.1416; class base { public: virtual void area() { cout << "base::area()" << endl; } }; class Triangle :public base { public: Triangle() { cout << "请输入三角形的底边a和高h:" << endl; cin >> a >> h; } void area() { cout << "三角形的面积是:" << a * h / 2 << endl; } private: float a, h; }; class Circle:public base { public: Circle() { cout << "请输入圆的半径:" << endl; cin >> r; } void area() { cout << "圆的面积是:" << PI * r * r << endl; } private: float r; }; int main() { base* b1, * b2;//定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。 b1 = new Triangle; b2 = new Circle; b1->area(); b2->area(); return 0; }
来源:https://www.cnblogs.com/nanaa/p/11967639.html