一. 多态与对象数组的问题
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) 多重继承可以通过精心设计用单例继承和接口来代替
注意: 接口只是一个功能说明,而不是功能实现。子类需要根据功能说明定义功能实现。