转换与继承--《C++ primer》笔记

转换与继承--《C++ primer》笔记

本文转载自转换与继承--《C++ primer》笔记

 

派生类到基类的转换

基本上可以直接转,就提取派生类的基类部分就行了,其余的“切掉”(忽略)

01.//派生类和基类的转换,想把派生类对象转成基类对象,基本上是各种直接间接的“复制”,通过copy-constructor 和operator=等形式,把派生类对象的基类部分赋予新对象  
02.#include<iostream>  
03.class Item_base{};  
04.class Bulk_item : public Item_base{};//注意此处,如果换成protecte和private,用户代码不能将派生类型对象转换为基类对象。  
05.class D2 : public Bulk_item{};  
06.int main(){  
07.    Item_base item1;            //object of base type  
08.    Bulk_item bulk;             //object of derived type  
09.    //ok:uses Item_base::Item_base(const Item_base&) constructor  
10.    //Item_base item2(bulk);        //bulk is "sliced down" to its Item_base portion  
11.    //ok:calls Item_base::operator=(const Item_base&)参数是基类的引用,把派生类的基类部分做原本复制或赋值给新对象  
12.      
13.    //不太明白什么叫使用转换,什么叫访问转换  
14.    D2 d2;  
15.    //public,用户代码和后代类都可以使用派生类到基类的转换  
16.    item1 = bulk;               //bulk is "sliced down" to its Item_base portion  
17.    Item_base item3(d2);  
18.      
19.    Bulk_item bulk2(d2);//语言容易误导,说protected继承的话,后续派生类的成员可以转换为基类类型,指的是这个直接基类Bulk_item,不是间接基类  
20.}  
21.class Derived;  
22.class Base {  
23.    Base(const Derived&);//create a new Base from a Derived  
24.    Base &operator=(const Derived&);  
25.};  


BaseToDerived

从基类到派生类的转换.因为包含关系,基类是不能直接自动转换为派生类对象的,除非间接(也就是利用基类的副本初始化派生类的基类部分,其余随便弄)

//基类到派生类的转换,是不可能自动发生的,因为兼容问题,派生类有基类部分,基类不可能有派生类部分
//所以要有条件的转换,说白了就是复制基类,利用基类部分给派生类的基类部分赋值,其他地方自动初始化一下
#include<iostream>

class Item_base {};
class Bulk_item : public Item_base {};

int main(){
	/*Item_base base;
	Bulk_item* bulkP = &base;	//error:can't convert base to derived
	Bulk_item& bulkRef = base;	//error:can't convert base to derived
	Bulk_item bulk = base;		//error:can't convert base to derived
	*/
	//更惊讶的是,即使原本是Bulk_item,因为指针“强制转换”成Item_base,再转成Bulk_item也不允许了
	Bulk_item bulk;
	Item_base *itemP = &bulk;	//ok:dynamic type is Bulk_item
	Item_base item;
	//Bulk_item *bulkP = itemP;	//error:can't convert base to derived
	//解决办法,强制转换(在知道这种情况,知道这样转换安全的前提下),dynamic_cast和dynamic_cast,后边介绍dynamic_cast
	//Bulk_item *bulkP = static_cast<Bulk_item*>(itemP);//本身是派生类,只是指针“认为”基类的,可以再转换回来
	//Bulk_item *bulkP = static_cast<Bulk_item*>(&item);
	Bulk_item bulkP = static_cast<Bulk_item>(item);
	//Bulk_item *bulkP = dynamic_cast<Bulk_item*>(itemP);
}

构造函数和复制控制:

派生类构造函数调用基类构造函数来初始化基类

#include<iostream>
class Item_base{//非派生类,一切正常
public:
	Item_base(const std::string &book = "", double sales_price = 0.0) :
		isbn(book), price(sales_price) {}
private:
	std::string isbn;
	double price;
};
/*只是隐式的调用Item_base的default constructor初始化对象的基类部分
class Bulk_item : public Item_base {//
public:
	Bulk_item() : min_qty(0), discount(0.0) {}
private:
	size_t min_qty;
	double discount;
};
*/
//显式
class Bulk_item : public Item_base {
public:
	Bulk_item(const std::string &book = "", double sales_price = 0.0,
	std::size_t qty = 0, double disc_rate = 0.0 ) :
		Item_base(book, sales_price), min_qty(qty), discount(disc_rate) {}
private:
	size_t min_qty;
	double discount;
};

int main(){
	//有默认实参,可以输入四种情况
	Bulk_item bulk1("0-201-82470-1", 50, 5, .19);
	Bulk_item bulk2("0-201-82470-1", 50, 5);
	Bulk_item bulk3("0-201-82470-1", 50);
	Bulk_item bulk4("0-201-82470-1");
	
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值