代码:
// 示例:多层继承,没有使用虚函数 #include <iostream> using namespace std; // 基类Base1 class Base1 { public: void display() const {cout << "Base1::display()" << endl; } }; // 派生类Base2,公有继承自Base1 class Base2:public Base1{ public: void display() const { cout << "Base2::display()" << endl; } }; // 派生类Derived,公有继承自Base2 class Derived: public Base2 { public: void display() const { cout << "Derived::display()" << endl;} }; void fun(Base1 *ptr) { ptr->display(); } int main() { Base1 base1; Base2 base2; Derived derived; // 观察:通过"对象名.成员名"访问类族中同名成员函数时运行结果 base1.display(); base2.display(); derived.display(); // 观察:通过公共接口函数fun(),利用基类指针访问同名成员函数时运行结果 fun(&base1); fun(&base2); fun(&derived); return 0; }
本题没有使用虚函数,因而根据同名覆盖原则,子类中的所有display()都继承父类,因而结果都为Base1:display();
2.
截图:
本题使用了纯虚函数,因而先按基类构造函数的顺序,再按内嵌函数的顺序进行,得到结果。两个实验的指针分别指向Base1中的display(),和子类Base中display()。
代码:
// 示例:多层继承,使用虚函数 #include <iostream> using namespace std; // 基类Base1 class Base1 { public: virtual void display() const {cout << "Base1::display()" << endl; } // 相较于ex1_1.cpp, 基类Base1中成员函数前添加了关键字virtual }; // 派生类Base2,公有继承自Base1 class Base2:public Base1{ public: void display() const { cout << "Base2::display()" << endl; } }; // 派生类Derived,公有继承自Base2 class Derived: public Base2 { public: void display() const { cout << "Derived::display()" << endl;} }; void fun(Base1 *ptr) { (*ptr).display(); } int main() { Base1 base1; Base2 base2; Derived derived; // 观察:通过"对象名.成员名"访问类族中同名成员函数时运行结果 base1.display(); base2.display(); derived.display(); // 观察:通过公共接口函数fun(),利用基类指针访问同名成员函数时运行结果 fun(&base1); fun(&base2); fun(&derived); return 0; }
3.
截图:
代码:
#include <iostream> #include <cmath> using namespace std; const float PI = 3.14; //抽象类Shape class Shape { public: virtual float area(); // 纯虚函数 }; // 派生类Rectangle供有继承自类Shape class Rectangle: public Shape { public: Rectangle() {} Rectangle(float l, float w): length(l), width(w) { } float area() { return length*width; } private: float length, width; }; // 派生类Cirle公有继承自类Shape class Circle: public Shape { public: Circle() {} Circle(float r): radius(r) { } float area() { return PI*radius*radius; } private: float radius; }; // 派生类Triangle公有继承自类Shape class Triangle: public Shape { public: Triangle() {} Triangle(float a, float b, float c):side1(a), side2(b), side3(c) { } float area() { float t; t = (side1 + side2 + side3) / 2; return sqrt( t*(t-side1)*(t-side2)*(t-side3) ); } private: float side1, side2, side3; }; // 接口函数,为打印图形面积提供了一个统一的功能接口,用于打印图形面积 // 形参是指向基类的指针,按照继承和派生机制中的赋值兼容原则,它也可以指向派生类的对象 void printArea(Shape *p) { cout << p->area() << endl; } int main() { Rectangle rect(3,4); Circle cc(2); Triangle tt(3,4,5); printArea(&rect); printArea(&cc); printArea(&tt); return 0; }
4.
电子宠物:
代码:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class MachinePets { 5 public: 6 virtual string talk()=0; 7 virtual string getnickname() = 0; 8 }; 9 class PetCats :public MachinePets { 10 public: 11 PetCats() {} 12 PetCats(string s) :nickname(s) {} 13 string getnickname(); 14 string talk() { 15 string a = "miao miao"; 16 return a; 17 } 18 private: 19 string nickname; 20 }; 21 class PetDogs :public MachinePets { 22 public: 23 PetDogs() {} 24 PetDogs(string s) :nickname(s) {} 25 string getnickname(); 26 string talk() { 27 string a = "wang wang"; 28 return a; 29 } 30 private: 31 string nickname; 32 }; 33 string PetCats::getnickname() 34 { 35 return nickname; 36 } 37 string PetDogs::getnickname() 38 { 39 return nickname; 40 } 41 void play(MachinePets* f) 42 { 43 cout <<f->getnickname()<<" "<<"says: "<< f->talk() << endl; 44 } 45 int main() { 46 PetCats cat("miku"); 47 play(&cat); // 按照play()形参,传递参数 48 // 按照play()形参,传递参数 49 PetDogs dog("da huang"); 50 play(&dog); 51 return 0; 52 }
截图:
本来此题按照上一题的解法并不困难,但我不小心将虚函数后多加了const;
virtual string talk()const=0 ;
错误 C2259 “PetCats”: 不能实例化抽象类 ConsoleApplication14 C:\Users\asus\source\repos\ConsoleApplication14\ConsoleApplication14.cpp 46
就是由于这个const,抽象类中拥有const,而派生类中没有const,因而会导致编译器将其看做两个不同的函数,会以为talk()没有重写,派生类依旧是抽象类,因而导致错误。
因而const一定不能前有后舍。
5.
rpg
原文:https://www.cnblogs.com/lszz/p/10923470.html