我是靠谱客的博主 傻傻万宝路,最近开发中收集的这篇文章主要介绍C++Prime 第十五章C++Prime 第十五章,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C++Prime 第十五章

练习15.1

虚成员:基类希望派生类覆盖的成员函数.任何构造函数之外的非静态函数都可以是虚函数.

练习15.2

protected: 允许派生类访问
private:不允许

练习15.3

#pragma once
#include <iostream>
#include <vector>
using namespace std;
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 { return n * price; }
virtual ~Quote() = default;	//对析构函数进行动态绑定
private:
string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote :public Quote
{
public:
double net_price(size_t n)const override;
};
double print_total(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 << endl;
}

练习15.4

(a) 不能派生自己
(b)ok
© 类派生列表不可出现在声明语句中.

练习15.5

#pragma once
#include <iostream>
#include <vector>
using namespace std;
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 { return n * price; }
virtual ~Quote() = default;	//对析构函数进行动态绑定
private:
string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote :public Quote
{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc)
:Quote(book, p), min_qty(qty), discount(disc) { }
double net_price(size_t n)const override;
private:
size_t min_qty = 0;//使用折扣政策的最低购买量
double discount = 0.0;//以小数表示的折扣额
};
double print_total(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 << endl;
}

练习15.6

int main()
{
Quote q;
Bulk_quote bq;
print_total(cout, q, 3);
print_total(cout, bq, 4);
return 0;
}

练习15.7

class my_Bulk_quote :public Bulk_quote
{
public:
my_Bulk_quote() = default;
my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m)
:Bulk_quote(book, p, qty, disc), max_qty(m) { }
double net_price(size_t n)const override;
private:
size_t max_qty = 0;
};
#include "Quote.h"
double Bulk_quote::net_price(size_t n) const
{
if (n >= min_qty)
return n * (1 - discount) * price;
else
return n * price;
}
double my_Bulk_quote::net_price(size_t n) const
{
if (n >= max_qty)
return (n - max_qty) * price + Bulk_quote::net_price(max_qty);
return Bulk_quote::net_price(n);;
}

练习15.8

静态类型:编译时已知,它是变量声明时的类型或表达式生成的类型.
动态类型:运行时才知道,是变量或表达式表示的内存中的对象的类型

练习15.9

基类的指针或引用的静态类型可能和其动态类型不一致.

Quote q1;
Bulk_quote q2;
Quote &p1 = q2;
Quote* p2 = &q2;

练习15.10

ifstream派生自istream,故其对象可以当成istream来使用

练习15.11

int main()
{
Quote q("倚天屠龙记",10);
Bulk_quote bq("降魔传",10,20,0.8);
my_Bulk_quote my_bq("系游", 5, 20, 0.9, 20);
q.debug();
cout << endl;
bq.debug();
cout << endl;
my_bq.debug();
cout << endl;
return 0;
}
#pragma once
#include <iostream>
#include <vector>
using namespace std;
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 { return n * price; }
virtual ~Quote() = default;	//对析构函数进行动态绑定
virtual void debug() { cout << "书名: "<<bookNo << ",单价: " << price; }
private:
string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote :public Quote
{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc)
:Quote(book, p), min_qty(qty), discount(disc) { }
double net_price(size_t n)const override;
void debug() {
Quote::debug();
cout << ",折扣政策的最低购买量: " << min_qty
<< ",折扣额: " << discount;
}
private:
size_t min_qty = 0;//使用折扣政策的最低购买量
double discount = 0.0;//以小数表示的折扣额
};
class my_Bulk_quote :public Bulk_quote
{
public:
my_Bulk_quote() = default;
my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m)
:Bulk_quote(book, p, qty, disc), max_qty(m) { }
auto net_price(size_t n) const ->double
override;
void debug() { Bulk_quote::debug(); cout << ",最大限额量: " << max_qty; }
private:
size_t max_qty = 0;
};

练习15.12

没有必要.假如是一个大于两层的继承体系.声明override表示将某个成员函数覆盖了,难保该类的派生类(第三层的继承类)不继续覆盖该成员函数,所以如果不是确信不会对其进行覆盖的情况下,不要用final.

练习15.13

有,无限递归,加上类限定符即可

练习15.14

(a)基类
(b)派生类
©基类
(d)派生类
(e)基类
(f)派生类

练习15.15

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; //表示折扣的小数值
};
class Bulk_quote :public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc)
:Disc_quote(book, p, qty, disc){ }
double net_price(size_t n)const override;
};
double Bulk_quote::net_price(size_t n) const
{
if (n >= quantity)
return n * (1 - discount) * price;
else
return n * price;
}

练习15.16

class my_Bulk_quote :public Disc_quote
{
public:
my_Bulk_quote() = default;
my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m)
:Disc_quote(book, p, qty, disc), max_qty(m) { }
auto net_price(size_t n) const ->double
override;
private:
size_t max_qty = 0;
};
double my_Bulk_quote::net_price(size_t n) const
{
if (n >= max_qty)
return (n - max_qty) * price + max_qty * (1 - discount) * price;
return n * (1 - discount) * price;;
}

练习15.17

不可以定义纯虚拟基类的对象

练习15.18

Base *p = &d1; //合法,基类指针或引用可以指向公有派生类.
p = &d2; //不合法,基类的指针或引用可以指向公有派生的类对象
p = &d3; //不合法,同上
p = &dd1; //合法,基类指针或引用可以指向公有派生类

练习15.19

Derived_from_private是错误的.
第二层的派生类肯定是毫无问题的,第三层的派生类必须继承自第二层公有或派生的类,才可以向基类转换

练习15.20

正确

int main()
{
pub_derive d1;
priv_derive d2;
prot_derive d3;
derived_from_private dd2;
derived_from_public
dd1;
derived_from_protected dd3;
myBase* p = &d1;
//p = &d2;
//p = &d3;
p = &dd1;
//p = &dd2;
//p = &dd3;
return 0;
}

练习15.21

练习15.22

#pragma once
#include <iostream>
#include <cmath>
const double PI = 3.141592657;
class Shape//ABC
{
public:
Shape() = default;
//默认构造函数
//其他函数无需定义
virtual ~Shape() {};
//虚析构函数
public:
//成员函数
double get_area() const;
//获得该图形的面积
virtual void calculate() = 0;
//纯虚函数,计算相关数据
virtual void debug() const = 0;
//输出所有数据
protected:
double area = 0;
//面积
};
class Square :public Shape
{
public:
Square(double n) :side_len(n) { calculate(); }
//使用边长进行构造
Square() = default;
//默认构造,边长初始化为0
//其他拷贝控制函数不需要
~Square() override { };
//虚析构,不用定义任何操作
public:
void calculate() override;
//重写
void debug() const override;
//输出所有数据
double get_perimeter() const;
//获得该图形的周长
private:
double side_len = 0;
//边长
double perimeter = 0;
//周长
};
class Round :public Shape
{
public:
Round() = default;
Round(double r) :radiu(r) { calculate(); }
~Round()override { }
public:
void calculate() override;
//纯虚函数,计算面积和周长
void debug()const override;
double get_perimeter() const;
//获得该图形的周长
private:
double radiu = 0;
//圆的半径
double perimeter = 0;
};
class Ball :public Shape
{
public:
//类的基础
Ball() = default;
Ball(double r) :radiu(r) { calculate(); }
~Ball()override { }
public:
//功能实现
void calculate()override;
//计算
void debug()const override;
double get_volumn()const;
//获得球的体积
private:
double radiu = 0;
//半径
double volumn = 0;
//体积
};
class Cone :public Shape
{
public:
Cone() = default;
Cone(double r, double h) :radiu(r), height(h) { calculate(); }
~Cone() override { }
public:
void calculate()override;
void debug() const override;
double get_volumn();
private:
double radiu = 0;
double height = 0;
double volumn = 0;
double mother_line = 0;
};
#include "Shape.h"
void Square::calculate()
{
area = side_len * side_len;
perimeter = 4 * side_len;
return;
}
void Square::debug() const
{
std::cout << "这是个方块!边长是: " << side_len
<< ",周长是: " << perimeter
<< ",面积是: " << area
<< std::endl;
}
double Square::get_perimeter() const
{
return perimeter;
}
double Shape::get_area() const
{
return area;
}
void Round::calculate()
{
area = PI * radiu * radiu;
perimeter = 2 * PI * radiu;
return;
}
void Round::debug() const
{
std::cout << "这是个圆!半径是: " << radiu
<< ",周长是: " << perimeter
<< ",面积是: " << area
<< std::endl;
}
double Round::get_perimeter() const
{
return perimeter;
}
void Ball::calculate()
{
area = 4 * PI * radiu * radiu;
volumn = PI * radiu * radiu * radiu * 4 / 3;
return;
}
void Ball::debug() const
{
std::cout << "这是个球!半径是: " << radiu
<< ",面积是: " << area
<<",体积是: "<<volumn
<< std::endl;
}
double Ball::get_volumn() const
{
return volumn;
}
void Cone::calculate()
{
mother_line = sqrt(height * height + radiu * radiu);
area = PI * radiu * mother_line + PI * radiu * radiu;
volumn = PI * radiu * radiu * height / 3;
return;
}
void Cone::debug() const
{
std::cout << "这是个圆锥!半径是: " << radiu
<<",高度是: "<<height
<<",母线长是: "<<mother_line
<< ",体积是: " << volumn
<< ",面积是: " << area << std::endl;
}
double Cone::get_volumn()
{
return volumn;
}
int main()
{
Square s(2);
Round r(3);
Ball b(4);
Cone c(6, 7);
vector<Shape* > pvec{&s,&r,&b,&c};//基类指针可以指向公有派生类对象
for (auto p : pvec)
p->debug();
return 0;
}

输出:

这是个方块!边长是: 2,周长是: 8,面积是: 4
这是个圆!半径是: 3,周长是: 18.8496,面积是: 28.2743
这是个球!半径是: 4,面积是: 201.062,体积是: 268.083
这是个圆锥!半径是: 6,高度是: 7,母线长是: 9.21954,体积是: 263.894,面积是: 286.882

练习15.23

去掉形参int.
Base bobj; D1 d1obj; D2 d2obj;
Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;

bp1->fcn(); //调用Base::fcn
bp2->fcn(); //调用Base::fcn()
bp3->fcn(); //调用D2::fcn

bp2->f2(); //报错,Base没有成员函数f2()
d1p->f2(); //调用D1::f2()
d2p->f2(); //调用D2::f2()

p1->fcn(42); //报错,base没有成员函数fcn(int)
p2->fcn(42); //报错,(未修改前不报错)
p3->fcn(42); //调用D2::fcn(int)

练习15.24

继承体系中的类分配了资源,该基类必须定义虚析构函数.
释放所分配的资源.

练习15.25

如果不给Disc_quote定义一个默认的构造函数,那么因为定义了自定义的构造函数,Disc_quote将没有默认构造函数.
那么它的派生类的默认构造函数将是被删除的.
将无法使用默认构造函数.

练习15.26

#pragma once
#include <iostream>
#include <vector>
using namespace std;
class Quote
{
public:
Quote(const Quote& q) ;
Quote(Quote&& q) ;
Quote& operator=(const Quote& q) ;
Quote& operator=(Quote&& q);
public:
Quote(const string& book = " ", double sales_price = 0.0) :bookNo(book), price(sales_price) { cout << "使用Quote的构造函数n"; }
string isbn()const { return bookNo; }
virtual double net_price(size_t n)const { return n * price; }
virtual ~Quote() = default;	//对析构函数进行动态绑定
virtual void debug() { cout << "书名: "<<bookNo << ",单价: " << price; }
private:
string bookNo;
protected:
double price = 0.0;
};
class Disc_quote :public Quote
{
public:
Disc_quote(const Disc_quote& d);
Disc_quote(Disc_quote&& d);
Disc_quote& operator=(const Disc_quote& d);
Disc_quote& operator=(Disc_quote && d);
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; //表示折扣的小数值
};
class Bulk_quote :public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc)
:Disc_quote(book, p, qty, disc){ }
double net_price(size_t n)const override;
};
class my_Bulk_quote :public Disc_quote
{
public:
my_Bulk_quote() = default;
my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m)
:Disc_quote(book, p, qty, disc), max_qty(m) { }
auto net_price(size_t n) const ->double
override;
//void debug() { Bulk_quote::debug(); cout << ",最大限额量: " << max_qty; }
private:
size_t max_qty = 0;
};

练习15.27

练习15.28

练习15.29

	vector<shared_ptr<Quote> > v;
v.push_back(make_shared<Bulk_quote>("0-123-12", 50, 10, 0.25));
v.push_back(make_shared<Bulk_quote>("0-sdf", 20, 15, 0.27));
double sum = 0;
for (const auto& p : v)
sum += p->net_price(8);
cout << sum << endl;

练习15.30

#pragma once
#include <vector>
#include <iostream>
#include <set>
#include "Quote.h"
using namespace std;
class Basket
{
public:
void add_item(const Quote& sales) {
items.insert(shared_ptr<Quote>(sales.clone()));
}
void add_item(Quote&& sales) {
items.insert(shared_ptr<Quote>(std::move(sales).clone()));
}
void add_item(const shared_ptr<Quote>& sale) { items.insert(sale); }
double total_receipt(ostream&)const;
private:
static bool compare(const shared_ptr<Quote> &lhs, const shared_ptr<Quote>& rhs )
{
return lhs->isbn() < rhs->isbn();
}
multiset<shared_ptr<Quote>, decltype(compare)* > items{ compare };
};

练习15.31

(a)Query(s1)生成一个WordQuery对象.然后生成一个OrQuery,右侧先生成WordQuery,然后变成NotQuery,最后生成一个AndQuery
(b)先生成WordQuery,然后NOtQuery,然后AndQuery最后NotQuery

练习15.32

最后一个例子及其剩下的题目暂时不做了,很久很久后会来补上的.

最后

以上就是傻傻万宝路为你收集整理的C++Prime 第十五章C++Prime 第十五章的全部内容,希望文章能够帮你解决C++Prime 第十五章C++Prime 第十五章所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部