C++语法13-基类与派生类对象之间的赋值兼容关系

在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量。在赋值之前,先把整型数据转换成为双精度型数据,然后再把它赋给双精度变量。这种不同类型数据之间的自动转换和赋值,称为赋值兼容。在基类和派生类对象之间也存在赋值兼容关系,基类和派生类对象之间的赋值兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。

通过前面的学习我们知道,通过公有继承,派生类保留了基类中构造函数、析构函数之外的所有成员,基类的公有或保护成员的访问权限在派生类中全部按原样保留了下来,在派生类外可以调用基类的公有成员函数访问基类的私有成员。因此,公有派生类具有基类的全部功能,凡是基类能够实现的功能,公有派生类都能实现。我们可以将派生类对象的值赋给基类对象,在用到基类对象的时候可以用其子对象代替。

根据赋值兼容规则,在基类Base的对象可以使用的任何地方,都可以使用派生类Derived的对象来替代,但只能使用从基类继承来的成员。具体表现在以下几个方面:

(1)派生类对象可以向基类对象赋值,即用派生类对象中从基类继承过来的数据成员,逐个赋值给基类对象的数据成员。

(2)派生类对象可以初始化基类对象的引用。

Base b; //定义基类Base的对象b

Derived d; //定义基类Base的公有派生类Derived的对象b

Base &br=d; //定义基类Base的对象的引用br,并用派生类Derived的对象d对其初始化

(3)派生类对象的地址可以赋给指向基类对象的指针。

Derived d;

Base *bp = &d;

(4)如果函数的形参是基类对象或基类对象的引用,在调用函数时可以用派生类对象作为实参。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base{
public:
int i;
...
};
class Derived:public Base{
...
};
class fun(Base &bb){
cout<<bb.i<<endl;
}

在调用函数fun时可以用派生类Derived的对象d4作为实参:
fun(d4);

下面是一个使用赋值兼容规则的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
using namespace std;
class Base{
public:
int i;
Base(int x){
i=x;
}
void show(){
cout<<"Base"<<i<<endl;
}
};
class Derived:public Base{
public:
Derived(int x):Base(x){}
};
void fun(Base &bb){
cout<<bb.i<<endl;
};
int main(){
Base b1(100);
b1.show();
Derived d1(11);
b1=d1; //用派生类对象d1给基类对象b1赋值
b1.show();
Derived d2(22); //用派生类对象d2来初始化基类对象的引用b2
Base &b2=d2;
b2.show();
Derived d3(33);
Base *b3=&d3; //把派生类对象的地址赋值给指向基类的指针b3
b3->show();
Derived d4(44);
fun(d4); //派生类的对象d4作为函数fun的实参

return 0;
}

说明:

(1)声明为指向基类对象的指针可以指向它的公有派生的对象,但不允许指向它的私有派生的对象。

1
2
3
4
5
6
7
8
9
10
11
12
class Base{
...
};
class Derived:private Base{
...
};
int main(){
Base op1,*ptr; //定义基类Base的对象op1及指向基类Base的指针ptr
Derive op2; //定义派生类Derived的对象op2
ptr=&op1; //将指针ptr指向基类对象op1
ptr=&op2; //错误,不允许将指向基类的Base的指针ptr指向它的私有派生类对象op2
}

(2)允许将一个声明为指向基类的指针指向其公有派生类的对象,但是不能将一个声明为指向派生类对象的指针指向其基类的一个对象。

1
2
3
4
5
6
7
8
9
10
11
class Base{
...
};
class Derived:public Base{
...
};
int main(){
Base obj1; //定义基类对象obj1
Derive obj2,*ptr; //定义派生类对象obj2及指向派生类的指针ptr
ptr=&obj2; //将指向派生类对象的指针ptr指向派生类对象ptr
ptr=&obj1; //错误,试图将指向派生类对象的指针ptr指向其基类对象obj1
-------------The End-------------
0%