第四部分:十五章 面向对象编程:派生

基本概念接触

基类与派生类,虚函数,多态,动态绑定

思想:共同点做基类的公共部分,保留每个派生类都具有的共性,然后根据各自特点override原来的virtual函数(成员),代码重用吧也算


dynamicBinding.cpp

//定义基类base class,虚函数virtual,protected权限,虚析构函数virtual destructor,动态绑定dynamic binding
//我看得MIT公开课,老头的微积分
//derivative是可导的,导数,还有派生,derived class
//十四章的integral是积分的,完整的
//多态性polymorphism,poly有聚乙烯的解释,morphism是摹式射,morph是水人,变体精灵
//继承层次inheritance(继承,遗产,创战纪Tron legacy也有遗产的意思) hierarchy(考研词汇) 
//bulk 大量的 批量的

#include<iostream>
class Item_base{
public:
//因为第一个参数有默认实参,第二个参数也必须要默认实参,
//这个设定是防歧义的么~单参会传递给第二个形参,而使用者意愿也许是给第一个
//这样就可以选择,0、1、2三种参数输入来调用
	Item_base(const std::string &book = "",
				double sales_price = 0.0):
					isbn(book), price(sales_price){}
public:
	std::string book()const {return isbn;}
	//虚函数,方便重新定义(不算重写吧?override,应该是重写,和java不太一样吧,忘了是直接写还是也要加标识覆盖了)
	//returns total sales price for specified number of items
	//derived classes will override and apply different discont algorithms
	virtual double net_price(std::size_t n) const {return n * price;}//net_price指网购价格?
	virtual ~Item_base(){}//析构也要override,虚析构函数,可能给自己方便,也可能给编译器看?后边有说。。
private:
	std::string isbn;
protected:
	double price;
};

void print_total(std::ostream &os, const Item_base &item, size_t n){
	os << "ISBN: " << item.book()
		<< "\tnumber sold: " << n << "\ttotal price: "
		<< item.net_price(n) << std::endl;
	
}
int main(){
	
	Item_base item1("asd", 22.8);
	print_total(std::cout, item1, 11);
	
}


构造函数和static不能为虚函数~~why?


Q:protected到底能被谁访问?派生类能访问,派生类的函数不能访问,那还怎么访问?


关键概念:

如果没有继承,类只有两种用户:类本身的成员和该类的用户。用private和public控制访问权限,只有成员和友元能访问privete。

有了继承,第三种用户叫做“从类派生定义新类的程序员”

三种类型的场合用途:public~公用接口;private~具体实现和数据;protect~为了一定程度满足派生类实现所需操作或数据的成员


派生类和虚函数:

基类有返回自身的引用或指针时,派生类可以定义为返回基类或派生类的指针(问题是如果我不声明呢,15.9节将介绍)


构造函数不可以是虚函数,析构函数必须要虚函数,析构未必大变动,有的都是自动,构造就不一样了,成员什么的,列表什么的,编译器可能没要求,原则上,不是要求构造函数初始化列表把所有成员都初始化么,这也是个需求(不过不是硬性要求吧,因为不是所有派生类成员都不同于基类吧


protected.cpp


#include<iostream>
class Item_base{
public://析构能虚,构造不能虚~!
	Item_base(const std::string &book = "",
				double sales_price = 0.0):
					isbn(book), price(sales_price){}
	virtual ~Item_base(){}
public:
	std::string book()const {return isbn;}
	virtual double net_price(std::size_t n) const {return n * price;}
	virtual Item_base* fcn(){return new Item_base("sd");}//返回基类指针或引用的虚函数
private:
	std::string isbn;
protected:
	double price;
};

class Bulk_item: public Item_base{
public://继承来的isbn不能在构造函数初始化列表中用。
	Bulk_item(const std::string &book = "",
				double sales_price = 0.0)
					{}
public:	
	void memfcn(const Bulk_item &d, const Item_base &b);	
public:
	double net_price(std::size_t) const;
private:
	//virtual double price;//派生类不能改变virtual现状,没有不能声明成有,有了声明不声明一样
	std::size_t min_qty;
	double discount;
	//std::string isbn2 = isbn;//说是继承来,实际上private看不到,看不到就继承不来?
	//std::string isbn2 = Bulk_item::isbn;//不能出现在常量表达式~!!
	//double isbn2 = Bulk_item::price;//protect要求用static~~~
};

double Bulk_item::net_price(std::size_t cnt) const{
	if(cnt >= min_qty)
		return cnt * (1 - discount) * price;
	else
		return cnt * price;
}
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b){
	double ret = price;
	ret = d.price;
	//ret = b.price;//err:no access to price from an Item_base
	//派生类能访问base class的protected member,派生类的函数不能访问,那怎么访问
	//是b.price的访问方式错误么?
}

void print_total(std::ostream &os, const Item_base &item, size_t n){
	os << "ISBN: " << item.book()
		<< "\tnumber sold: " << n << "\ttotal price: "
		<< item.net_price(n) << std::endl;
	
}
int main(){
	
	Item_base item1("asd", 22.8);
	print_total(std::cout, item1, 11);
	
	Bulk_item item2("Asdad", 22.1);
	print_total(std::cout, item2, 13);
}

1.用作基类的类必须是已定义的,因此自己继承自己是错误的。

2.前向声明不能有类派生列表(class derivation list)

所以,如下声明:

class Item_base;
class Bulk_item;//正确的前向声明 forward declarations of both derived and nonderived class


class Item_base{/*...*/};
class Bulk_item : public Item_base{/*...*/} 
因为Item_base只声明没定义之前,Bulk_item也只是声明,没定义( 这个类派生列表不知道叫他声明的列表部分还是叫他定义的一部分合适呢)继承Item_base,直到后边Item_base的定义完成(不定义会出错,invalid use of incomplete type 'struct Item_base'),才开始继承,测试成功~!

pe15_5.cpp

class Base{};
//class Derived : public Derived{};//err:~继承自己,自己还是incomplete的。(这不是前向声明,有花括号)
//class Derived : Base{};//正确?没声明public的话,默认是什么?这个权限是设给谁看的?前边的理解好像都错了?
//声明public代表只继承接口?声明private也继承不出来私有成员啊
//class Derived : private Base{};//看不出来错
//class Derived : public Base;//典型的前向声明错误,没有{/*实现*/},所以不是定义,多了类派生列表,是不正确的声明
class Derived inherits Base{};//看不懂,expected initializer before 'Base'

pe15——6.cpp

//定义自己的Bulk_item
#include<iostream>

class Item_base{
public://析构能虚,构造不能虚~!
	Item_base(const std::string &book = "",
				double sales_price = 0.0):
					isbn(book), price(sales_price){}
	virtual ~Item_base(){}
public:
	std::string book()const {return isbn;}
	virtual double net_price(std::size_t n) const {return n * price;}
	virtual Item_base* fcn(){return new Item_base("sd");}//返回基类指针或引用的虚函数
private:
	std::string isbn;
protected:
	double price;
};


class Bulk_item : public Item_base{
public:
	Bulk_item(std::size_t min = 10, double dis = 0.75, double price = 22.5): min_qty(min), discount(dis), price(price) {}
	double net_price(std::size_t n){
		return price * n * (n > min_qty ? discount : ORIGIN);
	}
private:
	std::size_t min_qty;
	double discount;
	static const double ORIGIN = 1.0;//ORIGIN代表不打折,为什么都要求static
	double price;//如果需要自己声明,还继承干嘛
};



int main(){
	Bulk_item item1;
	std::cout << item1.net_price(11) << std::endl;//打完折比那个还便宜,我应该给个折扣的智能算法,不能让消费者占便宜。。。。
	std::cout << item1.net_price(9) << std::endl;
}

说是都继承了,比如protect double price,到底怎样引入呢?都提示看不到,要什么时候才能使用,整个类定义完?那我构造函数怎么初始化它





















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值