15.11
Quote中的debug方法
//15.11
virtual void debug(){
std::cout<<this->bookNo<<std::endl;;
std::cout<<this->price<<std::endl;
}
Bulk_quote类中的方法,注意,此时bookNo已经不能访问,因为它是private的,只能基类自己访问,派生类不能访问
//15.11
void debug() override{
std::cout<<this->isbn()<<std::endl;;
std::cout<<this->price<<std::endl;
std::cout<<this->min_qty<<std::endl;
std::cout<<this->discount<<std::endl;
}
15.12
有
override是声明本方法是覆盖基类方法,final是修饰不可继续呗派生类进行覆盖
两者并不冲突
当需要覆盖基类的虚函数并且不能让本类的派生类重写的时候,就可以这样写
15.13
class base {
public:
string name() { return basename;}
virtual void print(ostream &os) { os << basename; }
private:
string basename;
};
class derived : public base {
public:
void print(ostream &os) { print(os); os << " " << i; }
private:
int i;
};
这里的问题在虚函数的重写上面,override表明函数身份,base::表明使用父类的print
应该改成
void print(ostream &os) override { base::print(os); os << " " << i; }
要不然编译没问题 但是调用的时候会产生无限循环
15.14
a,基类的print
b,派生类的print
c,基类的name
d,派生类中属于基类的name::这里因为派生类是没有name这个方法的,所以派生类的对象中包含着基类的部分就会有这个方法
e,此处动态类型是基类,所以是基类的print
f,此处动态类型是派生类,所以是调用的是派生类的print
15.15
QUOTE_H_INCLUDED
#define QUOTE_H_INCLUDED
class Quote{
public:
Quote() = default;
Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
std::string isbn() const {return bookNo;}
//返回给定数量的书籍的销售总额
//派生类负责改写并使用不同的折扣计算方法
virtual double net_price(std::size_t n) const{ return n*price;}
virtual ~Quote() = default; //对析构函数进行动态绑定
//15.11
virtual void debug(){
std::cout<<this->bookNo<<std::endl;;
std::cout<<this->price<<std::endl;
}
private:
std::string bookNo;
protected:
double price = 0.0;
};
//用于保存折扣值和购买量的类,派生类使用这些数据可以实现不同的价格策略
class Disc_quote:public Quote{
public:
Disc_quote() = default;
Disc_quote(const std::string & book,double price,std::size_t qty,double disc):
Quote(book,price),
quantity(qty),discount(disc){}
double net_price(std::size_t) const = 0;
protected:
std::size_t quantity = 0; //折扣适用的购买量
double discount = 0.0; //表示折扣的小数值
};
class Bulk_quote : public Disc_quote{
public:
Bulk_quote() = default ;
Bulk_quote(const std::string & book,double p , std::size_t qty,double disc):Disc_quote(book,p,qty,disc){}
double net_price(std::size_t n) const override;
//15.7
double new_price(std::size_t a,std::size_t b) const;
//15.11
void debug() override{
std::cout<<this->isbn()<<std::endl;;
std::cout<<this->price<<std::endl;
std::cout<<this->min_qty<<std::endl;
std::cout<<this->discount<<std::endl;
}
private:
std::size_t min_qty = 0; //适用折扣政策的最低购买量
double discount = 0.0; //以小数表示的折扣
};
//当同一书籍的销量超过某个值是启动折扣
double print_total(std::ostream &os,const Quote &item,size_t n){
//根据传入的形参的对象类型调用quote::net_price;
//或者Bulk_quote::net_price;
double ret = item.net_price(n);
os<<"ISBN: "<<item.isbn()<<" # sold"<<n<<" total due: "<<ret<<std::endl;
return ret;
}
double Bulk_quote::net_price(std::size_t cnt) const {
if(cnt >= min_qty)
return cnt*(1-discount) * price;
else{
return cnt * price;
}
}
//新购物打折策略
double Bulk_quote::new_price(std::size_t cnt,std::size_t use_count) const {
if(cnt<=use_count){ //折扣数目内
return cnt*price*(1-discount);
}else{ //折扣数目外
return use_count*price*(1-discount)+(cnt-use_count)*price;
}
}
#endif // QUOTE_H_INCLUDED
15.16
class new_quote : public Disc_quote
{
public:
new_quote() = default;
new_quote(const std::string& str, double price, std::size_t max, double disc) :
Disc_quote(str, price, max, disc)
{}
double net_price(std::size_t n) const override
{
return n * price * (n < quantity ? 1 - discount : 1);
}
};
15.17
Disc_quote s;
因为含有绝对的虚函数,所以产生报错,报错为
C:\wook_tool\MyCppSpace\primer_15_1\main.cpp|20|error: cannot declare variable 's' to be of abstract type 'Disc_quote'|
15.18
本题目的知识点十分简单
Base *p = &d1; //d1 的类型是 Pub_Derv,这是合法的,父类的指针指向子类的引用
p = &d2; //d2 的类型是 Priv_Derv 这是不合法的,因为只有Derv公有的继承Base是,用户代码才能使用派生类向基类的转换,像第一行一样
p = &d3; //d3 的类型是 Prot_Derv 不合法,理由同上
p = &dd1; //dd1 的类型是 Derived_from_Public 合法,因为Derived_from_Public 继承直接基类间接基类都共有的,所以符合第一条语句的条件
p = &dd2; //dd2 的类型是 Derived_from_Private 不合法,理由同上,用户代码的向基类转化的问题
p = &dd3; //dd3 的类型是 Derived_from_Protected 不合法,同上
15.19
•Pub_Derv 合法
•Priv_Derv 合法
•Prot_Derv 合法
前三个因为不论以什么样的方式继承,该直接派生类的成员函数和友元都能使用派生类到基类的转换
•Derived_from_Public 合法
如果继承的方式是共有的或者受保护的,则该派生类的派生类的成员和友元可以使用直接派生类到基类的转换,
•Derived_from_Protected 合法 :理由同上
•Derived_from_Private类中不合法 理由同上
15.20
#ifndef BASE_H_INCLUDED
#define BASE_H_INCLUDED
class Base{
public:
void pub_mem(){} //public成员
void memfcn(Base &b){b = *this;}
protected:
int prot_mem; //protected受保护的成员
private:
char priv_mem; //private私有的成员
};
//派生访问符的目的是控制 派生类用户(包括派生类的派生类在内)对于基类成员的访问权限
struct Pub_Derv:public Base{
int f(){return prot_mem;} //正确,派生类可以访问基类的protected成员
//char g(){return this->priv_mem;} //错误,private成员对于派生类来说是不可以访问的
void memfcn(Base &b){b = *this;}
};
struct Priv_Derv : private Base{
int f1() const {return prot_mem;} //private不影响派生类的访问权限
void memfcn(Base &b){b = *this;}
};
struct Prot_Derv : protected Base{
int f2() const {return prot_mem;} //private不影响派生类的访问权限
void memfcn(Base &b){b = *this;}
};
struct Derived_from_Public : public Pub_Derv{
int use_base(){return prot_mem;} //上上层基类中的受保护属性还可以继续使用
void memfcn(Base &b){b = *this;}
};
struct Derived_from_Private: public Priv_Derv{
//int use_base(){return prot_mem;} //受到直接父类的继承修饰词private的限制
};
struct Derived_from_Protected: public Prot_Derv{
//int use_base(){return prot_mem;} //受到直接父类的继承修饰词private的限制
void memfcn(Base &b){b = *this;}
};
#endif // BASE_H_INCLUDED
继续验证第18题
#include <iostream>
#include"Base.h"
#include"Base1.h"
int main()
{
Pub_Derv d1;
Base *p = &d1; //d1 的类型是 Pub_Derv
Priv_Derv d2;
//p = &d2; //d2 的类型是 Priv_Derv
Prot_Derv d3;
//p = &d3; //d3 的类型是 Prot_Derv
Derived_from_Public dd1;
p = &dd1; //dd1 的类型是 Derived_from_Public
Derived_from_Private dd2;
//p = &dd2; //dd2 的类型是 Derived_from_Private
Derived_from_Protected dd3;
//p = &dd3; //dd3 的类型是 Derived_from_Protected
return 0;
}
15.21与22
#ifndef FLOWER_H_INCLUDED
#define FLOWER_H_INCLUDED
class Flower{
public:
Flower() = default;
Flower(std::string &s,std::string &n){
species = s;
name = n;
}
//开花方法
virtual void flowering()const = 0;
protected:
std::string species;
private:
std::string name;
};
class GreenF:public Flower{
public:
GreenF();
GreenF(std::string &s,std::string &n,std::string &p):Flower(s,n),price(p){}
//实现开花方法
void flowering() {
std::cout<<"这是绿色的花"<<std::endl;
}
protected:
std::string price;
};
class RedF:public Flower{
public:
RedF();
RedF(std::string &s,std::string &n,std::string &p):Flower(s,n),price(p){}
//实现开花方法
void flowering() {
std::cout<<"这是红色的花"<<std::endl;
}
protected:
std::string price;
};
#endif // FLOWER_H_INCLUDED
15.23
将括号内的int函数移除








网友评论