《c++primer》第15章面对对象程序设计习题解答

练习15.1:什么是虚成员?

在类中声明为virtual的成员函数,基类希望这种成员函数在派生类中被重新定义。除了构造函数不能被定义为虚成员函数为,其他的任意非static成员函数可以定义为虚成员函数(也就是说析构函数可以定义为虚成员函数)

练习15.2:protected访问说明符与private有何区别?

protected是受保护的访问说明符,意味着被protected声明的成员可以被该类的成员、友元以及该类的派生类成员(非友元)访问,但不能被该类的对象访问。
而private声明的成员,只能被该类的成员和友元访问,该类的派生类不能访问。

练习15.3:定义你自己的Quote类和print_total函数。


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;       //对析构函数进行动态绑定
private:
    std::string bookNo;             //书籍的ISBN编号
protected:
    double price=0.0;               //代表普通状态下不打折的价格
};

注:此类为书上定义的Quote类。


练习15.4:下面哪条声明语句是不正确的?请说明原因。

class Base {  …  };
(a) class Derived : public Derived { … };
(b) class Derived : private Base  { … };
(c) class Derived : public Base;


(a)不正确,一个类本身不能从自己派生而来

(b)正确

(c)不正确,声明类的时候,不可以包含派生列表,只有在定义类的时候才派生列表。


练习15.5:定义你自己的Bulk_quote类

class Bulk_quote : public Quote
{
public:
	double net_price( size_t cnt ) const override
	{
		if ( cnt >=min_qty )
			return cnt * ( 1- discount ) * price;
		else
			return cnt * price;
	}

private:
	size_t min_qty;
	double discount;
};


练习15.6:将Quote类和Bulk_quote的对象传给15.2.1节(第529页)练习中的print_total函数,检查该函数是否正确。

略。


练习15.7:定义一个类使其实现一种数量受限的折扣策略,具体策略是:当购买书籍的数量不超过一个给定的限量时享受折扣,如果购买量一旦超过了限量,则超出的部分将以原价销售。

class Limited_quote : public Quote
{
public:
	double net_price( size_t cnt ) const override
	{
		if ( cnt <=min_qty )
			return cnt * ( 1- discount ) * price;
		else
			return min_qty*(1-discount)*price+(cnt-min_qty) * price;
	}
    
private:
	size_t min_qty;
	double discount;
};


练习15.8:给出静态类型和动态类型的定义。

静态类型在编译时就已经确定了,它是变量声明时的类型或表达式生成的类型;而动态类型则是变量或表达式表示的内存中的对象的类型,动态类型直到运行时才能知道。
如:
Quote *pQuote =new Bulk_quote;

指针pQuote的静态类型是Quote,在编译时就已经确定了。但是它的动态类型是Bulk_quote,直到运行时才能知道它指向的是基类还是派生类。
如果一个变量非指针也非引用,则它的静态类型和动态类型永远一致。但基类的指针或引用的动态类型可能与其动态类型不一致。


练习15.9:在什么情况下表达式的静态类型可能与动态类型不同?请给出三个静态类型与动态类型不同的例子。

Bulk_quote bulk;
Quote *pQuote=&bulk;
Quote &rQuote=bulk;

只知道两个,第三个不知道,o(╯□╰)o


练习15.10:回忆我们在8.1节(第279页)进行的讨论,解释第284页中将ifstream传递给Sales_data的read函数的程序是如何工作的。

在要求使用基类型对象的地方,可以使用派生类型的对象来代替。


练习15.11:为你的Quote类体系添加一个名为debug的虚函数,令其分别显示每个类的数据成员。

#include <iostream>
using namespace std;
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 void debug()
    {
        cout<<"bookNo="<<bookNo<<" price="<<price<<endl;
    }
    virtual ~Quote()=default;       //对析构函数进行动态绑定
private:
    std::string bookNo;             //书籍的ISBN编号
protected:
    double price=0.0;               //代表普通状态下不打折的价格
    
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值