[C++] C++继承和虚函数 →→→→→进入此内容的聊天室

来自 , 2019-08-17, 写在 C++, 查看 152 次.
URL http://www.code666.cn/view/c215b446
  1. //C++继承和虚函数(具体见附件)
  2.  
  3.  
  4. //-----------继承--inheritance:------------
  5. //程序1:
  6. #include<iostream>
  7. using namespace std;
  8. class Person{
  9. protected:
  10.   string name;//由于是protected类型,故在子类里面可以访问
  11. private:
  12.   bool gender;
  13. public:
  14.   Person(const char *a,bool g=true):name(a),gender(g){}
  15.   void show()
  16.   {
  17.     cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<endl;
  18.     cout<<",很高兴认识大家!"<<endl;
  19.   }
  20.   void eat(const char *food)
  21.   {
  22.     cout<<"我喜欢吃"<<food<<"."<<endl;
  23.   }
  24. };
  25.  
  26. class Student:public Person{
  27.   int gread;
  28.   string major;
  29. public:
  30.   //公有继承父类的,可以访问它里面的公有成员以及受保护的成员
  31.   //如果在子类构造函数里面要初始化父类里面的成员,就把相应的参数传给
  32. //父类的构造函数
  33.   Student(const char *a,bool g,int G,const char *m)
  34.   :gread(G),major(m),Person(a,g){}//注意这里对父类成员的初始化
  35.   void show()//改写来自父类成员,隐藏父类的同名成员
  36.   {
  37.     cout<<"大家好,我是"<<name<<endl;
  38.     cout<<",很高兴认识大家!"<<endl;
  39.   }
  40.   void details()
  41.   {
  42.     cout<<"我现在是大学"<<gread<<"年级学生,"<<name<<"我的专业是"<<major;
  43.     cout<<",希望一起交流!"<<endl;
  44.   }
  45. };
  46. int main()
  47. {
  48.   Person a("铁蛋",true);
  49.   a.show();
  50.   a.eat("火腿肠");
  51.   Student b("胖妞",false,3,"信息");
  52.   b.show();
  53.   b.eat("火腿");
  54.   b.details();
  55. }
  56.  
  57.  
  58. //----------多重继承、虚继承:------------
  59.  
  60.  
  61. //虚继承:
  62. //1.来自虚基类的成员合并,只保留一份到最下层子类里面
  63. //2.虚基类构造函数的参数,由底层子类直接传递
  64. //3.虚继承,保证虚基类的成员到最底层子类里面只保留一份
  65. #include<iostream>
  66. using namespace std;
  67. class Goods{
  68.   double price;
  69. public:
  70.   Goods(double p=100):price(p){cout<<"Goods()"<<endl;}
  71.   ~Goods(){cout<<"~Goods()"<<endl;}
  72.   //double Price()
  73.   void Price()
  74.   {
  75.     //return price;
  76.     cout<<price<<endl;
  77.   }
  78. };
  79. class Camera:virtual public Goods{
  80. public:
  81.   Camera(double p):Goods(p){cout<<"Camera()"<<endl;}
  82.   ~Camera(){cout<<"~Camera()"<<endl;}
  83.   void take(const char* obj)
  84.   {
  85.     cout<<"给"<<obj<<"照相."<<endl;
  86.   }
  87. };
  88. class MP3:virtual public Goods{
  89. public:
  90.   MP3(double p):Goods(p){cout<<"MP3()"<<endl;}
  91.   ~MP3(){cout<<"~MP3()"<<endl;}
  92.   void play(const char *song)
  93.   {
  94.     cout<<"播放歌曲<<"<<song<<">>"<<endl;
  95.   }
  96. };
  97. class Phone:virtual public Goods{
  98. public:
  99.   Phone(double p):Goods(p){cout<<"Phone()"<<endl;}
  100.   ~Phone(){cout<<"~Phone()"<<endl;}
  101.   void dial(const char *no)
  102.   {
  103.     cout<<"给"<<no<<"拨打电话!"<<endl;
  104.   }
  105. };
  106. //多重继承,构造函数执行的顺序是按照子类继承父类的顺序执行
  107. //同时,子类的构造函数是最后执行(即一个类总是先调用父类的构造函数)
  108. class ModernPhone:public Phone,public Camera,public MP3
  109. {
  110.   string factory;
  111. public:
  112.   ModernPhone(const char *f,double p):factory(f),Phone(p),Camera(p),MP3(p),Goods(p)
  113.   {
  114.     cout<<"ModernPhone()"<<endl;
  115.     cout<<"手机厂商"<<factory<<endl;
  116.   }
  117.   ~ModernPhone(){cout<<"~ModernPhone"<<endl;}
  118.   void visitnet(const char *url)
  119.   {
  120.     cout<<"访问网址"<<url<<endl;
  121.   }
  122. };
  123. int main()
  124. {
  125.   ModernPhone mp("Apple",300);
  126.   mp.dial("18710831610");
  127.   mp.play("最炫民族风");
  128.   mp.Price();
  129.   return 0;
  130. }
  131.  
  132. //--------虚函数、多态---(polymorphism[pɒlɪ'mɔːfɪz(ə)m]):------------
  133. //程序1:
  134. //通过指针调用虚函数的时候才会实现多态
  135. #include<iostream>
  136. using namespace std;
  137. class Person{
  138. protected:
  139.   string name;
  140. private:
  141.   bool gender;
  142. public:
  143.   Person(const char *a,bool g=true):name(a),gender(g){}
  144.   virtual void show()//虚函数
  145.   {
  146.     cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<endl;
  147.     cout<<",很高兴认识大家!"<<endl;
  148.   }
  149.   void eat(const char *food)
  150.   {
  151.     cout<<"我喜欢吃"<<food<<"."<<endl;
  152.   }
  153. };
  154.  
  155. class Student:public Person{
  156.   int gread;
  157.   string major;
  158. public:
  159.   Student(const char *a,bool g,int G,const char *m)
  160.   :gread(G),major(m),Person(a,g){}
  161.   void show()
  162.   {
  163.     cout<<"大家好,我是"<<name<<endl;
  164.     cout<<",很高兴认识大家!"<<endl;
  165.   }
  166.   void details()
  167.   {
  168.     cout<<"我现在是大学"<<gread<<"年级学生,"<<name<<"我的专业是"<<major;
  169.     cout<<",希望一起交流!"<<endl;
  170.   }
  171. };
  172. int main()
  173. {
  174.   Person a("铁蛋",true);
  175.   Student b("胖妞",false,3,"信息");
  176.   Person *p,*q;   //注意这里,p,q两个指针都是Person类型
  177.   p=&a;
  178.   q=&b;
  179.   //会根据对象的类型来决定调用那个对象里面的成员函数
  180.   a.show();
  181.   b.show();
  182. }
  183.  
  184. //程序2:
  185. //构造函数、析构函数中没有多态
  186. #include<iostream>
  187. using namespace std;
  188. class USB{
  189. public:
  190.   virtual void recognise()
  191.   {
  192.     cout<<"正在识别USB..."<<endl;
  193.   }
  194.   virtual void know()
  195.   {
  196.     cout<<"USB已经接入!"<<endl;
  197.   }
  198.   virtual void display()
  199.   {
  200.     cout<<"USB开始工作."<<endl;
  201.   }
  202. };
  203. //后面的子类里面的成员函数可以不写virtual,默认加virtual
  204. class USBCamera:public USB{
  205.   void recognise()
  206.   {
  207.     cout<<"正在识别相机..."<<endl;
  208.   }
  209.   void know()
  210.   {
  211.     cout<<"相机已经接入!"<<endl;
  212.   }
  213.   void display()
  214.   {
  215.     cout<<"相机开始工作."<<endl;
  216.   }
  217. };
  218. class USBMP3:public USB{
  219.   void recognise()
  220.   {
  221.     cout<<"正在识别MP3..."<<endl;
  222.   }
  223.   void know()
  224.   {
  225.     cout<<"MP3已经接入!"<<endl;
  226.   }
  227.   void display()
  228.   {
  229.     cout<<"MP3开始工作."<<endl;
  230.   }
  231. };
  232. class Computer{
  233. public:
  234.   void use(USB *p)//相当于,用父类申明一个指针,然后用改指针指向相应的成员函数
  235.   {
  236.     p->recognise();
  237.     p->know();
  238.     p->display();
  239.   }
  240. };
  241. int main()
  242. {
  243. //由于父类的成员函数已经申明为虚函数(virtual),所以在调用函数时,会根据相应的子类对象而调用子类里面的成员函数
  244.   USBCamera ca;
  245.   USBMP3 m;
  246.   Computer c;
  247.   c.use(&ca);
  248.   c.use(&m);
  249.   return 0;
  250. }
  251.  
  252.  
  253. //--------------纯虚函数:-------------
  254. //程序1:
  255. //只有用new创建对象,用delete释放对象,虚析构才起作用
  256. //构造、析构函数没有纯虚函数
  257. //子类一定是父类,所以可以将一个子类赋给父类,但父类不一定能够赋给子类
  258. #include<iostream>
  259. using namespace std;
  260. class Animal{
  261. public:
  262.   Animal(){}
  263.   virtual ~Animal(){}//虚析构
  264.   //~Animal(){shout();}
  265.   void play()
  266.   {
  267.     eat();
  268.     shout();
  269.     sleep();
  270.   }
  271.   //纯虚函数:提供一个接口,子类覆盖它,自己实现函数的不同功能
  272.   //有纯虚函数的类,称为抽象类abstract class
  273.   //补允许创建抽象类的对象
  274.   virtual void eat()=0;
  275.   virtual void shout()=0;
  276.   virtual void sleep()=0;
  277. };
  278. class Horse:public Animal{
  279. public:
  280.   Horse(){cout<<"马"<<endl;}
  281.   ~Horse(){cout<<"死马"<<endl;}
  282.   virtual void eat(){cout<<"马吃草"<<endl;}
  283.   virtual void shout(){cout<<"马叫"<<endl;}
  284.   virtual void sleep(){cout<<"马睡觉"<<endl;}
  285. };
  286. class Tiger:public Animal{
  287. public:
  288.   Tiger(){cout<<"老虎"<<endl;}
  289.   ~Tiger(){cout<<"死老虎"<<endl;}
  290.   virtual void eat(){cout<<"老虎吃肉"<<endl;}
  291.   virtual void shout(){cout<<"老虎叫"<<endl;}
  292.   virtual void sleep(){cout<<"老虎睡觉"<<endl;}
  293. };
  294. int main()
  295. {
  296.   char c;
  297.   Animal *p=NULL;
  298.   cout<<"选择h代表马,t代表老虎:";
  299.   cin>>c;
  300.   if(c=='h')
  301.     p=new Horse;
  302.   else
  303.     p=new Tiger;
  304.   p->play();
  305.   delete p;
  306.   //Animal a;这里编译出现错误,补允许创建抽象类的对象
  307.   return 0;
  308. }
  309.  
  310.  
  311. //程序2:
  312. //虚函数表里存有这个类里面所有虚函数的地址
  313. //每个类只有一个虚函数表,每个对象有一个指针指向这个虚函数表
  314. #include<iostream>
  315. using namespace std;
  316. class A{
  317.   double a;
  318. };
  319. class B{
  320.   double b;
  321.   void fun(){}
  322. };
  323. class C{
  324.   double c;
  325.   virtual void fun(){}
  326. };
  327. class D{
  328.   double d;
  329.   virtual void fun1(){}
  330.   virtual void fun2(){}
  331.   virtual void fun3(){}
  332. };
  333. int main()
  334. {
  335.   cout<<sizeof(A)<<endl;//8
  336.   cout<<sizeof(B)<<endl;
  337.   //sizeof(B)=8,函数在代码区,b在数据区,所以sizeof(b)=8
  338.   cout<<sizeof(C)<<endl;
  339.   //sizeof(C)=12,有虚函数的类,每个对象有一个虚指针,
  340.   //指向一个存有所有虚函数的数组,只占4个字节,与虚函数的个数无关
  341.   cout<<sizeof(D)<<endl;//sizeof(D)=12
  342.   return 0;
  343. }
  344.  
  345.  

回复 "C++继承和虚函数"

这儿你可以回复上面这条便签

captcha