C ++ _ programming_basis_3 (object-oriented design, inheritance derived)

#include<iostream>
#include<string>
#include<list>
#include<vector>
using namespace std;

//派生类的声明不包含派生列表
//但是类需要声明吗 为什么不声明也可用
class bulk_quote;
int main() {

	
	system("pause");
	return 0;
}
//我们要开始面对对象programming辣
//面对对象设计
class quote {
public:
	quote() = default;//默认
	quote(const string &book,double sales_price):
		bookNo(book),price(sales_price){}

	string isbn()const { return bookNo; }

	virtual double net_price(size_t n)const {//基类中把想要别人覆盖的定义为virtual
		return n * price;}//虚函数 那么这些函数在运行时(遇到实参类型)才解析
	
	virtual ~quote() = default;//对析构函数进行动态绑定
private:
	string bookNo;
protected:			//protected是派生类可以访问而其他用户禁止访问 但究其访问方式还是不简单的 只鞥通过对象访问 不得自身访问
	double price = 0.0;
};



class bulk_quote :public quote  {//这是类的继承  派生类public private protected
public:
	//构造函数用来初始化类,默认运行  成员函数时用来实现功能的,需要时自行调用
	bulk_quote() = default;
	bulk_quote(const string & book, double p, size_t qty, double disc) :
		quote(book,p),min_qty(qty),discount(disc){}//这是一个覆盖 构造函数(构造函数定义不准放在类外面哈)
	//上面请注意,基类quote两个参数初始化 然后两个派生类参数再初始化
	double net_price(size_t)const override;//基类中virtual该覆盖并不必须覆盖 没覆盖的话就自动继承了
	//还有就是在派生类中覆盖基的虚函数时 形参类型必须和覆盖的那个一致 而且返回类型也必须一致
	//在派生中覆盖虚函数时用这个override作用在于 假如你形参出错或非虚函数等等导致没覆盖上 那么这个override会帮你报错
	//假如我们在函数后头加final了  那么任何企图覆盖都会报错
private:
	size_t min_qty = 0;
	double discount = 0.0;//可以新增加成员 
};
	//如果要防止类的继承,也就是不希望别人继承这个类,就在这个类名后跟final

//以上是两个类 一个基一个派生


double print_total(ostream &os, const quote &item, size_t n) {
	double ret = item.net_price(n);
	os << "isbn: " << item.isbn() << "# sold " << n << " total price " << ret << endl;
	return ret;
}


//在运行时由实参决定选择函数的版本

double bulk_quote::net_price(size_t cnt)const {//用以说明派生类可以使用基类的成员 (public and protected is available)
	if (cnt >= min_qty)
		return cnt * (1 - discount)*price;
	else
	{
		return cnt * price;
	}
}
//使用指针或引用调用虚函数就会发生 动态绑定 而每一个虚函数都必须有定义
//因为只有执行到运行时才知道使用哪个函数 完全依赖于运行时的实参类型

//纯虚函数
class disc_quote :public quote {//这是一个抽象基类 不准创建这个类的对象
public:			//含有纯虚函数的类就叫抽象基类
	disc_quote() = default;
	disc_quote(const string& book,double price,size_t qty,double disc):
		quote(book,price),quantity(qty),discount(disc){//这里表示的是把接受到的四个参数分别传递给构造函数(说的是它直接继承的基类的),初始化俩成员
	//我们从这儿就能看出构造函数之所以为构造函数了
	}
	double net_price(size_t)const = 0;//纯虚函数
protected:
	size_t quantity = 0;
	double discount = 0.0;

};
class Bulk_quote :public disc_quote {
public:
	Bulk_quote() = default;
	Bulk_quote(const string& book,double price,size_t qty,double disc)://又到了接受参数然后传递的时候了
		disc_quote(book,price,qty,disc){}//是这样的,这个构造函数把接受的参数传递给disc_quote也就是他继承的哪个类
	//然后呢 disc_quote执行其构造函数又会分配参数最后调用quote的构造
};//这也就是类的继承的继承的参数传递以及构造函数发挥初始化运行过程

//访问控制与继承
class base {
protected:
	int prot_mem;
};

class sneaky :public base {
	friend void clobber(sneaky&);
	friend void clobber(base&);
	int j;
};

//派生类的成员或有缘只能通过派生类对象来访问基类的protected,其派生类自身对基类对象的protected没有访问特权
void clobber(sneaky& s) { s.j = s.prot_mem = 0; }//这个可以访问是因为成员函数可访问本类的private
//但是要想通过成员函数访问base的private就会报错 只能通过对象访问
//?????
//注意 他们的访问权限在于派生类对象中的基类部分的protected,而不是基类对象中的该成员

//友元关系不可以继承


Published 44 original articles · won praise 9 · views 3385

Guess you like

Origin blog.csdn.net/puying1/article/details/83713949