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

派生类到基类的转换

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

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

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");
	
}





//直接间接的初始化,找到了,特例是通过派生类构造函数函数体初始化,能给基类成员直接初始化。

//只能初始化直接基类,间接的就不行了 is not a direct base of class...
//书中号称派生类构造函数可以给基类public或protected成员赋值,HOW?试不出来does not have any field named 'discount'
//~~!!!!~~~~是在派生类构造函数的“函数体”内初始化基类成员--见quantity的初始化(即使把利用基类构造函数间接初始化quantity的语言删了也可以)
#include<iostream>
class Item_base{//非派生类,一切正常
public:
    Item_base(const std::string &book = "", double sales_price = 0.0) :
        isbn(book), price(sales_price) {}
    double net_price(std::size_t) const;
private:
    std::string isbn;
    double price;
};

class Disc_item : public Item_base {
public:
    Disc_item(const std::string& book = "", double sales_price = 0.0, std::size_t qty = 0.0, double disc_rate = 0.0) :
        Item_base(book, sales_price), quantity(qty), discount(disc_rate) { }
    std::size_t getQty() { return quantity; }
protected:
    std::size_t quantity;    //purchase size for discount to apply
    double discount;        //fractional discount to apply
};
//discount kicks in when a specified number of copies of same book are sold
//the discount is expressed as a fraction to use to reduce the normal price
class Bulk_item : public Disc_item {
public:
    Bulk_item(const std::string& book = "", double sales_price = 0.0, std::size_t qty = 0, double disc_rate = 0.0) :
        Disc_item(book, sales_price, qty, disc_rate) {quantity = qty + 8;}
    //redefines base version so as to implement bulk purchase discount policy
    double net_price(std::size_t) const;
};
int main(){
    Bulk_item bulk;
    std::cout << bulk.getQty() << std::endl;
}



15.15题,因为他英文那些东西,分类就搞不清楚,有book,有record,又视频video,有视频游戏video game的,还children's puppet,没法理解,随便分类,意思一下就行了。

pe15_16.cpp

练习题

其他的都简单,不知到下边这个怎么样,也是属于没遵守接口,直接访问id了吧,同构造函数体内初始化基类成员稍有不同,性质应该差不多。

struct C4 : public Base {
	C4(int val) : Base(id + val) { }
};









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值