什么是派生类的基类子对象?_第10章 继承性和派生类(177181视频汇总)

177继承性和派生类_继承中的二义性

178继承性和派生类_例10_12

179继承性和派生类_虚基类

180继承性和派生类_虚基类实例1

181继承性和派生类_虚基类实例2

10.3.3  多继承中的二义性1. 多继承中派生类对基类成员访问在下列两种情况下可能出现二义性。
(1) 访问不同基类的相同成员时可能出现二义性
例如,C类有两个直接基类A类和B类,其中,A类和B类中都有一个公有成员函数f( ),并且C类公有继承A和B,这时当C类的对象c1,访问基类成员f( )时,c1.f( )则会出现二义性。

1482140718ee6fdfe3c31ee03fe7f471.png

class A
{
public:
    void f();
};
class B
{
public:
    void f();
    void g();
};
class C:public A,public B
{
public:
    void g();
    void h();
};(2) 访问共同基类的成员时可能出现二义性
例如,当一个派生类有多个基类,而这些基类中又有一个共同的基类,这时候对这个共同的基类中成员的访问可能出现二义性。

c06620192b194cda72e67683bd10f834.png


class A
{
public:
    int a;
};
class B1:public A
{
private:
    int b1;
};
class B2:public A
{
private:
    int b2;
};
class C:public B1,public B2
{
public:
   int    f()
{
       return  B1::a+B2::a;
}
private:
    int b3;
};
例10.12
#include
class A
{
public:
A(int i) { a=i; cout<void print() { cout<~A() {cout<private:
int a;
};
class B1:public A
{
public:
B1(int i,int j):A(i) { b1=j; cout<void print() { A::print(); cout<~B1() { cout<private:
int b1;
};
class B2:public A
{
public:
B2(int i,int j):A(i) { b2=j; cout<void print() { A::print(); cout<~B2() { cout<private:
int b2;};
class C:public B1,public B2
{
public:
C(int i,int j,int k,int l,int m):B1(i,j),B2(k,l),c(m)
{ cout<void print()
{
    B1::print();
    B2::print();
cout<}
~C() { cout<private:
int c;
};
void main()
{
C c1(1,2,3,4,5);
c1.print();
}
派生类C的对象初始化的时候要两次调用共同间接基类A的构造函数,对类A中的数据成员也要进行两次初始化。10.4 虚基类
10.4.1虚基类的概念

在前面讲过的具有公共基类的例子中,当创建一个C类的对象时要两次调用A类的构造函数,如果只想调用一次A类构造函数时,则须在A类作为B1、B2类基类时将其定义为虚基类。
定义虚基类的方法如下:
class B1:virtual public A
{…}
class B2:virtual public A
{…}
定义为虚基类后也可以避免二义性。当定义虚基类后,A,B1,B2和C类之间的关系如下:

7245d16357c2210519a24cb9e790930a.png


class A
{
public:
    int a;
};
class B1: virtual public A
{
private:
    int b1;
};
class B2: virtual public A
{
private:
    int b2;
};
 class C:public B1,public B2
{
public:
   int    f()
{
       return   a;
}
private:
    int b3;
};10.4.2  含有虚基类的派生类的构造函数
 具有虚基类的派生类的构造函数中不仅包含两个直接基类的构造函数,另外还包含虚基类A的构造函数,并且规定虚基类A的构造函数优先调用,只调用一次,在B1类和B2类的构造函数中不再调用A类的构造函数。
#include
class A
{
public:
A(const char *s) { cout<~A() {}
};
class B:virtual public A
{
public:
B(const char *s1,const char *s2):A(s1)
{cout<};
class C:virtual public A
{
public:
C(const char *s1,const char *s2):A(s1)
{ cout<};
class D:public B,public C
{public:
D(const char *s1,const char *s2,const char *s3,const char *s4)
:B(s1,s2),C(s1,s3),A(s1)
{
cout<};
void main()
{D *ptr=
new D("class A","class B","class C","class D");
delete ptr;
}1.在整个继承结构中,直接或间接继承虚基类的所有派生类都必须在构造函数初始化表中给出对虚基类的构造函数的调用,如果未列出,则表示调用虚基类的缺省构造函数,来初始化派生类对象中的子对象。
2.规定只在建立对象的最远派生类类的构造函数中调用虚基类的构造函数,而该派生类的基类构造函数中忽略对虚基类构造函数的调用,这样就保证了对象虚基类的子对象只初始化化一次。应用举例
#include
#include
#include
typedef char string80[80];
class Date
{public:
Date() {}
Date(int y,int m,int d) { SetDate(y,m,d);}
void SetDate(int y,int m,int d)
{ Year=y;
Month=m;
Day=d;
}
void GetStringDate(string80 &Date)
{ sprintf(Date,"%d/%d/%d",Year,Month,Day);
}
protected:
int Year,Month,Day;//年月日
};
class Time
{public:
Time() {}
Time(int h,int m,int s) { SetTime(h,m,s);}
void SetTime(int h,int m,int s)
{ Hours=h;
Minutes=m;
Seconds=s;
}
void GetStringTime(string80 &Time)
{ sprintf(Time,"%d:%d:%d",Hours,Minutes,Seconds);
}
protected:
int Hours,Minutes,Seconds;
};
class TimeDate:public Date,public Time
{
public:
TimeDate():Date() {}
TimeDate(int y,int mo,int d,int h,int mi,int s):
Date(y,mo,d),Time(h,mi,s)
{}
void GetStringDT(string80 &DTstr)
{sprintf(DTstr,"%d/%d/%d;%d:%d:%d",Year,Month,Day,Hours,Minutes,Seconds);
} };
void main()
{TimeDate date1,date2(1998,8,12,12,45,10);
string80 DemoStr;
date1.SetDate(1998,8,7);
date1.SetTime(10,30,45);
date1.GetStringDT(DemoStr);
cout<date1.GetStringDate(DemoStr);
cout<date1.GetStringTime(DemoStr);
cout<date2.GetStringDT(DemoStr);
cout<}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值