C++Primer第15章:面向对象程序设计(习题解答)

前言

考虑到时间的紧迫性,不可能在像之前那样又是抄题并且全部完成了,这次我只写到30题,剩下的是一个综合练习,就不搞了-.-

15.2.1节练习

15.1

在类中被声明为virtual的成员,基类希望这种成员在派生类中重定义,除了构造函数外,任意非
static成员都可以为虚成员

15.2

protected可以被该类的成员,友元和派生类成员访问,而不可以被该类型的普通成员访问,而private
成员只能被基类和友元访问,派生类不可访问

15.3

#include<bits/stdc++.h>

using namespace std;

class Quote
{
public:
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){};
     double net_price(std::size_t n)const
    {
        return n*price;
    }
    double print_total(ostream&os,const Quote&item,size_t n)
    {
        double ret=item.net_price(n);
        os<<"ISBN:"<<item.price<<"#sold:"<<n<<endl;
        return ret;
    }
    virtual~Quote()=default;
private:
    std::string bookNo;
protected:
    double price=0.0;
};

int main()
{
    Quote a("1001",10);
    auto ret=a.print_total(cout,a,4);
    cout<<ret<<endl;
    return 0;

}

15.2.2节练习

15.4

class base{...}

(a)class Derived :public Derived{...}//错误,不能自己作为基类,又是派生类
(b)class Derived:private Base{...}//正确
(c)class Derived:public Base;//正确

15.5

class Bulk_quote:public Quote
{
public:
    Bulk_quote()=default;
    Bulk_quote(const std::string&,double,std::size_t ,double);
    double net_price(std::size_t n)const;
private:
    std::size_t min_qty=0;
    double discount=0.0;
};
Bulk_quote::Bulk_quote(const std::string &s,double n,std::size_t min,double dis):Quote(s,n),min_qty(min),discount(dis){};
double Bulk_quote::net_price(std::size_t n)const
{
    return n*price*discount;
}

15.6

#include<bits/stdc++.h>

using namespace std;

class Quote
{
public:
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){};
    virtual double net_price(std::size_t n)const
    {
        return n*price;
    }
    virtual~Quote()=default;
private:
    std::string bookNo;
protected:
    double price=0.0;
};
 double print_total(ostream&os,const Quote&item,size_t n)
    {
        double ret=item.net_price(n);
        os<<ret<<endl;
        return ret;
    }

class Bulk_quote:public Quote
{
public:
    Bulk_quote()=default;
    Bulk_quote(const std::string&,double,std::size_t ,double);
    double net_price(std::size_t n)const override;
private:
    std::size_t min_qty=0;
    double discount=0.0;
};
Bulk_quote::Bulk_quote(const std::string &s,double n,std::size_t min,double dis):Quote(s,n),min_qty(min),discount(dis){};
double Bulk_quote::net_price(std::size_t n)const
{
    return n*price*discount;
}
int main()
{
    Quote a("1001",10);
    auto ret=print_total(cout,a,4);
    cout<<ret<<endl;
    Bulk_quote b("werqw",11,1,0.3);
    auto ans=print_total(cout,b,4);
    cout<<ans<<endl;

    return 0;

}

15.7

#include<bits/stdc++.h>

using namespace std;

class text
{
public:
    text(int a,int b,double c):max_num(a),price(b),discount(c){};
    void print_total(ostream&os,size_t num)
    {
        if(num<=max_num)
        {
            os<<num*price*discount<<endl;
        }else
        {
            os<<max_num*price*discount+(num-max_num)*price<<endl;
        }
        return;
    }
private:
    int max_num;
    int price;
    double discount;
};

int main()
{
    text a(100,3,0.3);
    a.print_total(cout,12);
    return 0;
}

15.2.3节练习

15.8

静态类型在编译时就确定好了,它是变量声明时的类型表达式生成的类型,而动态类型则是变量或者表达式表示内存中的对象的类型,其知道运行才会知道

15.9

传递给的是派生类对象则是其不同的情况

15.10

在要求使用基类对象的地方,允许使用派生类型对象来代替

15.3节练习

15.11

virtual void debug() {
        cout << "bookNo:" << bookNo << " price:" << price << endl;
    }

15.12

有必要,这就表示这个函数覆盖其基类的函数,有不能由其子类覆盖

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;};//加上override关键字修饰
	private:
		int i;
}

15.14

不想写,只要记住指针和引用类型可以实现运行时绑定即可。

15.4节练习

#include<iostream>

using namespace std;
class Quote
{
public:
    virtual void debug() {
        cout << "bookNo:" << bookNo << " price:" << price << endl;
    }
    Quote() = default;
    Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {};
    virtual double net_price(std::size_t n)const
    {
        return n * price;
    }
    virtual~Quote() = default;
private:
    std::string bookNo;
protected:
    double price = 0.0;
};
double print_total(ostream& os, const Quote& item, size_t n)
{
    double ret = item.net_price(n);
    os << ret << endl;
    return ret;
}
//Disc_quote
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 n)const = 0;
protected:
    std::size_t quantity = 0;
    double discount = 0;
};
class Bulk_quote :public Disc_quote{
public:
    Bulk_quote() = default;
    Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {};
    double net_price(std::size_t)const override;
}; 
double Bulk_quote::net_price(std::size_t n)const {
    if (n > quantity) {
        return price * quantity * discount + (n - quantity) * price;
    }
    else {
        return n * price * discount;
    }
}
int main() {
    Bulk_quote a("hello", 2, 3, 0.1);
    cout << a.net_price(10) << endl;
    return 0;
}

15.16

同上

15.17

不允许使用抽象类型的对象

15.5节练习

15.18

Base*p=&d1;//d1的类型是Pub_Derv 
p=&d2;//d2的类型是Priv_Derv  
p=&d3;//d3的类型是Prot_Derv
p=&dd1;//dd1的类型是Derived_from_Public
p=&dd2;//dd2的类型是Derived_from_Private
p=&dd3;//dd3的类型是Derived_from_Protected
只有当公有的继承时,才能进行派生类到基类的转换

15.19

void memfun(Base&b){b=*this};
同上,只有当时公有的继承时,才能进行派生类到基类的转化

15.20

不想作答-.-

15.21

记住普通用户实现代码,需要对象的接口,所以设为公有的,而实现者则是负责编写类的成员和友元,成员和友元可以访问对象所有
如果进一步考虑继承,就会出现第三种用户,即派生类,基类把它希望派生类能够使用的部分设置为保护的,不同用户不能访问保护区,而派生类及其友元
仍然不能访问私有成员

15.22

根据上题思想来设计

15.6节练习

15.23

参数类型相同来进行覆盖

15.7.1节练习

15.24

基类需要虚析构函数,啥操作都不需要执行

15.7.2节练习

15.25

对象的实例化时,没有参数也能实例化

15.26

#include<iostream>

using namespace std;
class Quote
{
public:
    virtual void debug() {
        cout << "bookNo:" << bookNo << " price:" << price << endl;
    }
    Quote(const Quote&);
    Quote() = default;
    Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {
        cout << "Quote contructor is running" << endl;
    }
    virtual double net_price(std::size_t n)const
    {
        return n * price;
    }
    virtual~Quote() {
        cout << "Quote destructor is running" << endl;
    }
private:
    std::string bookNo;
protected:
    double price = 0.0;
};
Quote::Quote(const Quote& rhs) {
    cout << "Quote" << endl;
    bookNo = rhs.bookNo;
    price = rhs.price;
}
double print_total(ostream& os, const Quote& item, size_t n)
{
    double ret = item.net_price(n);
    os << ret << endl;
    return ret;
}
//Disc_quote
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) {
        cout << "Disc_quote constructor is running" << endl;
    }
    ~Disc_quote() {
        cout << "Dis_quote destructor is running" << endl;
    }
    double net_price(std::size_t n)const = 0;
protected:
    std::size_t quantity = 0;
    double discount = 0;
};
class Bulk_quote :public Disc_quote{
public:
    Bulk_quote(const Bulk_quote&);
    Bulk_quote() = default;
    Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {
        cout << "Bulk_qutoe constructor is running" << endl;
    }
    double net_price(std::size_t)const override;
    ~Bulk_quote() {
        cout << "Bulk_quote destructor is running" << endl;
    }
}; 
double Bulk_quote::net_price(std::size_t n)const {
    if (n > quantity) {
        return price * quantity * discount + (n - quantity) * price;
    }
    else {
        return n * price * discount;
    }
}
Bulk_quote::Bulk_quote(const Bulk_quote& hs) {
    cout << "Bulk_quote" << endl;
    //Quote(hs);
}
int main() {
    //Disc_quote b;
    Bulk_quote a("hello", 2, 3, 0.1);
    //cout << a.net_price(10) << endl;
    return 0;

15.27

class Bulk_quote :public Disc_quote{
public:
    using Disc_quote::Disc_quote;
    Bulk_quote(const Bulk_quote&);
    /*Bulk_quote() = default;
    Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {
        cout << "Bulk_qutoe constructor is running" << endl;
    }*/
    double net_price(std::size_t)const override;
    ~Bulk_quote() {
        cout << "Bulk_quote destructor is running" << endl;
    }
};

15.28

 vector<Quote>vec;
    Bulk_quote a("hello", 2, 3, 0.1);
    Quote b("helli", 2);
    vec.emplace_back(a);
    vec.emplace_back(b);
    for (auto& num : vec)cout << num.net_price(2) << endl

15.29

  vector<Quote>vec;
    Bulk_quote a("hello", 4, 5, 0.8);
    Quote b("helli", 2);
    vec.emplace_back(a);
    vec.emplace_back(b);
    //cout << a.net_price(2) << endl;
    //cout << b.net_price(2) << endl;
    for (auto& num : vec)cout << num.net_price(2) << endl;
    //text
    vector<shared_ptr<Quote>>vec1;
    Quote* iter = &a;
    cout << iter->net_price(2) << endl;
    vec1.emplace_back(make_shared<Bulk_quote>("hello",4,5,0.8));
    vec1.emplace_back(make_shared<Quote>("helli",2));
   // cout << vec1[0]->net_price(2) << endl;

    for (auto& num : vec1)cout << num->net_price(2) << endl

15.8.1节练习

15.30

#include<iostream>
#include<vector>
#include<set>
using namespace std;
class Quote
{
public:
    friend class Bulk_quote;
    virtual void debug() {
        cout << "bookNo:" << bookNo << " price:" << price << endl;
    }
    virtual Quote* clone()const & { return new Quote(*this); }
    virtual Quote* clone()&& { return new Quote(std::move(*this)); }
    Quote(const Quote&);
    Quote() = default;
    Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {
       // cout << "Quote contructor is running" << endl;
    }
    virtual double net_price(std::size_t n)const
    {
        return n * price;
    }
    virtual~Quote() {
       // cout << "Quote destructor is running" << endl;
    }
    string& isbn() { return bookNo; }
private:
    std::string bookNo;
protected:
    double price = 0.0;
};
Quote::Quote(const Quote& rhs) {
   // cout << "Quote" << endl;
    bookNo = rhs.bookNo;
    price = rhs.price;
}
double print_total(ostream& os, const Quote& item, size_t n)
{
    double ret = item.net_price(n);
    os << ret << endl;
    return ret;
}
//Disc_quote
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) {
        //cout << "Disc_quote constructor is running" << endl;
    }
    ~Disc_quote() {
        //cout << "Dis_quote destructor is running" << endl;
    }
    double net_price(std::size_t n)const = 0;
protected:
    std::size_t quantity = 0;
    double discount = 0;
};
class Bulk_quote :public Quote{
public:
    void debug() { cout << "quantity:" << quantity <<" bookNo:"<<isbn()<< endl; };
    Bulk_quote* clone()const& { return new Bulk_quote(*this); };
    Bulk_quote* clone()&& { return new Bulk_quote(std::move(*this)); };
    //using Disc_quote::Disc_quote;
    Bulk_quote(const Bulk_quote&);
    Bulk_quote() = default;
    Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Quote(book, price),quantity(qty),discount(disc) {
       // cout << "Bulk_qutoe constructor is running" << endl;
    }
    double net_price(std::size_t)const override;
    ~Bulk_quote() {
       // cout << "Bulk_quote destructor is running" << endl;
    }
protected:
    std::size_t quantity = 0;
    double discount = 0;

}; 
double Bulk_quote::net_price(std::size_t n)const {
    if (n > quantity) {
        return price * quantity * discount + (n - quantity) * price;
    }
    else {
        return n * price * discount;
    }
}
Bulk_quote::Bulk_quote(const Bulk_quote& hs) {
    price = hs.price;
    bookNo = hs.bookNo;
    quantity = hs.quantity;
    discount = hs.discount;
}
//Basket类
class Basket {
public:
    //加入
    void add_item( const Quote& sale) {
       // std::make_shared<Quote>(sale.clone())->debug();
        items.insert(std::shared_ptr<Quote>(sale.clone()));
        
    }
    void add_item(Quote&& sale) {
        items.insert(std::shared_ptr<Quote>(std::move(sale).clone()));
    }
    double total_receipt(std::ostream&)const;
private:
    static bool compare(const std::shared_ptr<Quote>& lhs, const std::shared_ptr<Quote>& rhs) {
        return rhs->isbn() < lhs->isbn();
    }
    std::multiset<std::shared_ptr<Quote>, decltype(compare)*>
        items{ compare };
};
double Basket::total_receipt(std::ostream& os)const
{
    double sum = 0;
    for (auto iter = items.cbegin();
        iter != items.cend(); iter = items.upper_bound(*iter)) {
        //cout << items.count(*iter) << endl;
        //(**iter).debug();
       // cout << (**iter).debug() << endl;
        sum += print_total(os, **iter, items.count(*iter));
       // cout << sum << endl;
    }
    cout << "Total Sale: " << sum << endl;
    return sum;
}
int main() {
    //Disc_quote b;
    vector<Quote>vec;
    Bulk_quote a("hello", 4, 6, 0.8);
   // a.clone()->debug();
    Bulk_quote c("hello", 4, 7, 0.7);
    Quote b("helli", 8);
    //b.clone()->debug();
    Quote d("helli", 9);
    Basket bask;
    bask.add_item(a);
    bask.add_item(a);
    bask.add_item(b);
    bask.add_item(c);
    bask.add_item(d);
     
    bask.total_receipt(cout);//输出
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值