#include<iostream>
#include<string>
//继承与组合:
// 继承:定义一个类作为另一个类的公用派生类时,派生类应反映与基类“是一种 Is a” 的关系。
// 组合:组合关系是“有一个Has a”的关系,通过“有一个”关系而相关的类型暗含有成员关系。
//友元关系不能继承,如果基类和派生类都需要访问另一个类,那个类必须特地将访问权限授予基类和每一个派生类。
/*
名字冲突:与基类成员同名的派生类成员将屏蔽对基类成员的直接访问。
纯虚函数:在函数形参表后面写上=0,就指定该函数为纯虚函数,例如:
class Disc_item:public Item_base{
public:
double net_price(std::size_t) const =0;
};
含有或继承一个或多个纯虚函数的类是抽象基类,除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象。
*/
using namespace std;
class Item_base{
public:
//构造函数
Item_base(const string &book="",double sales_price=10.0):isbn(book),price(sales_price){}
//返回书名函数
string book() const{
return isbn;
}
//虚函数,希望被继承,irtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
virtual double net_price(size_t n) const{
return n*price;
}
//虚析构函数,继承层次的根类一般都要定义虚析构函数
virtual ~Item_base(){}
// void print_total(ostream &os,const Item_base &item,size_t n){
// os<<"ISBN:"<<item.book()<<"\tnumber sold: "<<n<<"\ttotal price: "<<item.net_price(n)<<endl;
// }
private:
string isbn;
protected:
//派生类只能通过派生类对象访问基类的protected成员,派生类对其基类类型对象的protected成员没有访问权限。
double price;
};
//派生类:class className:access-label base-class
//access是public、protect或private访问标志符,该访问标志符决定了对继承成员的访问控制。
class Bulk_item: public Item_base{
public:
//派生类型必须对想要重定义的每个继承成员进行声明,即使没有定义(如果没有定义,则使用基类中定义的版本)
double net_price(size_t) const;
Bulk_item(int min=5,double disco=0.5):min_qty(min),discount(disco){}
private:
size_t min_qty;
double discount;
};
//派生类函数可以在类内部或外部定义
double Bulk_item::net_price(size_t cnt) const{
//cout<<cnt<<" "<<min_qty<< " "<<discount<<endl;
if(cnt >= min_qty)
{
// cout<<"this????"<<endl;
return cnt*(1.0-discount)*price;
}
else
return cnt*price;
}
//打印函数
void print_total(ostream &os,const Item_base &item,size_t n){
os<<"ISBN:"<<item.book()<<"\tnumber sold: "<<n<<"\ttotal price: "<<item.net_price(n)<<endl;
}
//练习:
struct Base{
Base(int val):id(val){}
protected:
int id;
};
/*
struct C1:public Base{
public:
C1(int val):id(val){
}
};
struct C2:public Base{
C2(int val):Base(id+val){}
};
struct C3:public Base{
C3(){}
};
//基类与派生类定义练习:
struct BaseTest{
void foo(int);
protected:
int bar;
double foo_bar;
};
struct DerivedTest:public BaseTest{
void foo(string);
bool bar(BaseTest *pb);
void foobbar();
protected:
string bar;
};
bool DerivedTest::bar(BaseTest *pb){
return foo_bar==pd->foo_bar;
}
*/
int main(){
Item_base base;
Bulk_item derived;
print_total(cout,base,10);
print_total(cout,derived,10);
return 0;
}