15.3类型转换与继承

类型转换与继承

理解基类与派生类的类型转换是理解C++语言面向对象编程的关键所在。

通常引用或者指针绑定的对象应与对象类型一致,或者含有一个可接受const类型的转换规则。但是继承关系的类是一个例外:我们可以将基类指针或引用绑定到派生类对象上。这隐含了一层重要的意义:当使用基类指针或引用时,我们不清楚该引用或指针所绑定对象的真实类型,可能是基类对象也可能是派生类对象。

1.静态类型与动态类型

首先我们得先明确几个名词的定义:

  • 静态类型:对象在声明时采用的类型在编译期确定,它是变量声明时的类型或表达式生成的类型。

  • 动态类型:变量或表达式表示的内存中的对象类型,通常是指一个指针或引用目前所指对象的类型,直到运行时才知道它的类型

  • 静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期

  • 动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期动态绑定只有当我们使用指针或引用调用虚函数时才会发生。

例如:

class Quote {...};
class BulkQuote : public Quote {...};
double printTotal(ostream &os, const Quote &item, int n) {
    //根据传入item的形参的对象类型调用netPrice函数
    double ret = item.netPrice(n);
    os << "ISBN:" << item.isbn()
       << "sold:" << n << "total due:" << ret << endl;
    return ret;
}
int main {
    Quote basic("abc", 100);
    printTotal(cout, basic, 20); //调用Quote的netPrice
}

当printTotal调用netPrice函数时,item的静态类型是Quote&,它的动态类型依赖于item绑定的实参,动态类型直到运行时调用该函数才会知道。当运行到printTotal(cout, basic, 20)时,传递给item的是Quote对象,因此item的动态类型是Quote的,当item调用了netPrice(20),这时发生了动态绑定

2.基类和派生类的类型转换

①不存在从基类向派生类的隐式转换

因为派生类包含基类,基类是派生类的一部分,因此可以从派生类转换到基类,不能从基类转换到派生类。

Quote base;
BulkQuote *bulkp = &base;  //错误:不能从基类转换到派生类
BulkQuote &bulkref = base; //错误:不能从基类转换到派生类

②在对象之间不存在类型转换

派生类向基类的自动转换只对指针或引用有效,在派生类类型和基类类型之间不存在这样的转换。

但是,当我们初始化或赋值一个类类型的对象时,实际上是在调用某个函数,拷贝初始化和拷贝赋值运算符的参数都是基类的引用的形式,因此可以用派生类对象来初始化基类对象,但是只有该派生类对象中的基类部分会被拷贝、移动或赋值,它的派生类部分将被忽略掉。

如:

BulkQuote bulk;        
Quote item(bulk);    //使用Quote(const Quote&)构造函数
item = bulk;         //使用operator==(const Quote&)
//将bulk的基类部分拷贝和赋值给item,忽略掉其派生类部分
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值