经典问题解析三

来源:互联网 发布:chart.js使用教程 编辑:程序博客网 时间:2024/05/01 23:25

一. 多态与对象数组的问题

class Parent{protected:int i;public:virtual  void f(){cout<<"Parent::f"<<endl;}};class Child:public Parent{protected:int j;public: Child(int i,int j){this->i = i;this->j= j;} void f(){cout<<"i="<<i<<" "<<"j="<<j<<endl;}};int main(int argc, char *argv[]){    Parent* p=NULL;    Child* c =NULL;    Child ca[3] = {Child(1,2),Child(3,4),Child(5,6)};       cout<<"sizeof(Parent)="<<sizeof(Parent)<<endl;   cout<<"sizeof(Child)="<<sizeof(Child)<<endl<<endl;           cout<<hex<<&ca[0]<<endl;    cout<<hex<<&ca[1]<<endl;    cout<<hex<<p<<endl;    cout<<hex<<c<<endl;    cout<<hex<<(p+1)<<endl;    cout<<hex<<(c+1)<<endl;        p = ca;    c = ca;        p->f();    c->f();        p++;    c++;       // p->f();  // 运行有问题     c->f();     return 0;}




   分析: 这是一个多态与数组对象,及指针运算符之间的问题。

       (1)父类中占8个字节,一个int类型,一个virtual函数,所以父类输出8个字节。

       (2) 子类继承了父类,同时又多个一个int类型,所以子类占12个字节。

       (3)p为父类指针,c为子类指针,p++的步长为8,c++的步长为12。


       (4)所以,当p++后,p->show(),出现段错误的原因所在。

二. 多重继承

    C++中对多继承二义性的解决方案

    虚继承:在继承间接共同基类时只保留一份成员。
           为了解决不同途径继承而来的同名数据成员造成的二义性问题,可以将共同基类设置为虚基类,

     。这样从不同的路径继承过来的同名数据成员在内存中只有一个拷贝。

     注意: 虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。

    实例:

#include <cstdlib>#include <iostream>using namespace std;#include <string>class Person{protected:string name;char sex;int age;public:Person(string nam,char s,int a):name(nam),sex(s),age(a){}};class Teacher:virtual public Person{protected:string title; // 职称public:Teacher(string nam,char s,int a,string t):Person(nam,s,a){title = t;} };class Student:virtual public Person{protected:float score; public:Student(string nam,char s,int a,float sco):Person(nam,s,a),score(sco){}};class Graduate:public Teacher,public Student{private:float wage;  // 津贴 public:Graduate(string nam,char s,int a,string t,float sco,float w):Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w){}void show(){cout<<"name:"<<name<<endl;cout<<"age:"<<age<<endl;cout<<"sex"<<sex<<endl;cout<<"score"<<score<<endl;cout<<"title"<<title<<endl;cout<<"wages"<<wage<<endl;} };int main(){Graduate gradl("Wang_li",'f',24,"assistant",89.5,1200);gradl.show();return 0;}



三. C++中接口类的实现

     (1) C++中没有接口的概念

     (2) C++中可以使用纯虚函数实现接口

class Interface1{public:virtual void print()=0;virtual int add(int i,int j)=0;};

class Interface2{public:virtual int add(int i,int j)=0;virtual int minus(int i,int j)=0;};

  接口类1 和接口类2 都有一个virtual int add(int i,int j)=0;

class Child:public Interface1,public Interface2{public:void print(){cout<<"Child::void print()"<<endl;}int add(int i,int j){return i+j;}int minus(int i,int j){return i-j;}};

   继承类中对两个接口中相同的函数值定义一次就行。

int main(){Child c;c.print();cout<<c.add(2,3)<<endl;cout<<c.minus(5,0)<<endl;Interface1* i1 =&c;Interface2* i2 =&c;cout<<i1->add(7,8)<<endl;cout<<i2->add(4,5)<<endl;return 0;}

    (1) 多重继承接口不会带来二义性和复杂性问题

    (2) 多重继承可以通过精心设计用单例继承和接口来代替

    注意: 接口只是一个功能说明,而不是功能实现。子类需要根据功能说明定义功能实现。












1 0