Skip to content

Commit

Permalink
ch15 ex15.27
Browse files Browse the repository at this point in the history
  • Loading branch information
huangmingchuan committed Mar 2, 2016
1 parent 93adeb3 commit 6f82d41
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 2 deletions.
16 changes: 16 additions & 0 deletions ch15/Bulk_quote.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include "Disc_quote.h"

class Bulk_quote : public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string& b, double p, std::size_t q, double disc) :
Disc_quote(b, p, q, disc)
{}

double net_price(std::size_t n) const override;
};

#endif // BULK_QUOTE_H
21 changes: 21 additions & 0 deletions ch15/Disc_quote.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef DISC_QUOTE_H
#define DISC_QUOTE_H

#include "exercise15_5.h"

class Disc_quote : public Quote
{
public:
Disc_quote();
Disc_quote(const std::string& b, double p, std::size_t q, double d) :
Quote(b, p), quantity(q), discount(d)
{}

virtual double net_price(std::size_t n) const override = 0;

protected:
std::size_t quantity;
double discount;
};

#endif // DISC_QUOTE_H
21 changes: 21 additions & 0 deletions ch15/Limit_quote.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef LIMIT_QUOTE_H
#define LIMIT_QUOTE_H

#include "disc_quote.h"

class Limit_quote : public Disc_quote
{
public:
Limit_quote() = default;
Limit_quote(const std::string& b, double p, std::size_t max, double disc) :
Disc_quote(b, p, max, disc)
{}

double net_price(std::size_t n) const override
{
return n * price * (n < quantity ? 1 - discount : 1);
}

};

#endif // LIMIT_QUOTE_H
47 changes: 45 additions & 2 deletions ch15/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ private:
```
在上述代码中存在问题吗?如果有,你该如何修改它?
有问题。应该改为:
```cpp
void print(ostream &os) override { base::print(os); os << " derived\n " << i; }
```

## 练习15.14

> 给定上一题中的类以及下面这些对象,说明在运行时调用哪个函数:
Expand All @@ -110,18 +115,31 @@ derived dobj; base *bp2 = &dobj; base &br2 = dobj;
(d)bp2->name(); (e)br1.print(); (f)br2.print();
```

* (a) 编译时。
* (b) 编译时。
* (c) 编译时。
* (d) 编译时。
* (e) 运行时。base::print()
* (f) 运行时。derived::print()

## 练习15.15

> 定义你自己的 Disc_quote 和 Bulk_quote。
[Disc_quote](Disc_quote.h) | [Bulk_quote](Bulk_quote.h)

## 练习15.16

> 改写你在15.2.2节练习中编写的数量受限的折扣策略,令其继承 Disc_quote。
[Limit_quote](Limit_quote.h)

## 练习15.17

> 尝试定义一个 Disc_quote 的对象,看看编译器给出的错误信息是什么?
`error: cannot declare variable 'd' to be of abstract type 'Disc_quote': Disc_quote d;`

## 练习15.18

> 假设给定了第543页和第544页的类,同时已知每个对象的类型如注释所示,判断下面的哪些赋值语句是合法的。解释那些不合法的语句为什么不被允许:
Expand All @@ -134,6 +152,13 @@ p = &dd2; //dd2 的类型是 Derived_from_Private
p = &dd3; //dd3 的类型是 Derived_from_Protected
```

* Base *p = &d1; 合法
* p = &d2; 不合法
* p = &d3; 不合法
* p = &dd1; 合法
* p = &dd2; 不合法
* p = &dd3; 不合法

## 练习15.19

> 假设543页和544页的每个类都有如下形式的成员函数:
Expand All @@ -142,7 +167,16 @@ void memfcn(Base &b) { b = *this; }
```
对于每个类,分别判断上面的函数是否合法。
## 练习15.20
合法:
* Pub_Derv
* Priv_Derv
* Prot_Derv
* Derived_from_Public
* Derived_from_Protected
不合法:
* Derived_from_Private
## [练习15.20](exercise15_20.cpp)
> 编写代码检验你对前面两题的回答是否正确。
Expand All @@ -163,19 +197,28 @@ void memfcn(Base &b) { b = *this; }

> 假设第550页的 D1 类需要覆盖它继承而来的 fcn 函数,你应该如何对其进行修改?如果你修改之后 fcn 匹配了 Base 中的定义,则该节的那些调用语句将如何解析?
移除 int 参数。

## 练习15.24

> 哪种类需要虚析构函数?虚析构函数必须执行什么样的操作?
基类通常应该定义一个虚析构函数。

## 练习15.25

> 我们为什么为 Disc_quote 定义一个默认构造函数?如果去掉该构造函数的话会对 Bulk_quote 的行为产生什么影响?
因为Disc_quote的默认构造函数会运行Quote的默认构造函数,而Quote默认构造函数会完成成员的初始化工作。
如果去除掉该构造函数的话,Bulk_quote的默认构造函数而无法完成Disc_quote的初始化工作。

## 练习15.26

> 定义 Quote 和 Bulk_quote 的拷贝控制成员,令其与合成的版本行为一致。为这些成员以及其他构造函数添加打印状态的语句,使得我们能够知道正在运行哪个程序。使用这些类编写程序,预测程序将创建和销毁哪些对象。重复实验,不断比较你的预测和实际输出结果是否相同,直到预测完全准确再结束。
## 练习15.27
[Quote](exercise15_26.h) | [Bulk_quote](exercise15_26_2.h)

## [练习15.27](exercise15_27.h)

> 重新定义你的 Bulk_quote 类,令其继承构造函数。
Expand Down
67 changes: 67 additions & 0 deletions ch15/exercise15_20.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <iostream>
#include <string>

#include "exercise15_5.h"
#include "bulk_quote.h"
#include "limit_quote.h"
#include "disc_quote.h"

class Base
{
public:
void pub_mem(); // public member
protected:
int prot_mem; // protected member
private:
char priv_mem; // private member
};

struct Pub_Derv : public Base
{
void memfcn(Base &b) { b = *this; }
};
struct Priv_Derv : private Base
{
void memfcn(Base &b) { b = *this; }
};
struct Prot_Derv : protected Base
{
void memfcn(Base &b) { b = *this; }
};

struct Derived_from_Public : public Pub_Derv
{
void memfcn(Base &b) { b = *this; }
};
struct Derived_from_Private : public Priv_Derv
{
//void memfcn(Base &b) { b = *this; }
};
struct Derived_from_Protected : public Prot_Derv
{
void memfcn(Base &b) { b = *this; }
};

int main()
{
Pub_Derv d1;
Base *p = &d1;

Priv_Derv d2;
//p = &d2;

Prot_Derv d3;
//p = &d3;

Derived_from_Public dd1;
p = &dd1;

Derived_from_Private dd2;
//p =& dd2;

Derived_from_Protected dd3;
//p = &dd3;


return 0;
}
78 changes: 78 additions & 0 deletions ch15/exercise15_26.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef QUOTE_H
#define QUOTE_H

#include <string>
#include <iostream>

class Quote
{
friend bool operator !=(const Quote& lhs, const Quote& rhs);
public:
Quote() { std::cout << "default constructing Quote\n"; }
Quote(const std::string &b, double p) :
bookNo(b), price(p)
{
std::cout << "Quote : constructor taking 2 parameters\n";
}

// copy constructor
Quote(const Quote& q) : bookNo(q.bookNo), price(q.price)
{
std::cout << "Quote: copy constructing\n";
}

// move constructor
Quote(Quote&& q) noexcept : bookNo(std::move(q.bookNo)), price(std::move(q.price))
{ std::cout << "Quote: move constructing\n"; }

// copy =
Quote& operator =(const Quote& rhs)
{
if (*this != rhs)
{
bookNo = rhs.bookNo;
price = rhs.price;
}
std::cout << "Quote: copy =() \n";

return *this;
}

// move =
Quote& operator =(Quote&& rhs) noexcept
{
if (*this != rhs)
{
bookNo = std::move(rhs.bookNo);
price = std::move(rhs.price);
}
std::cout << "Quote: move =!!!!!!!!! \n";

return *this;
}

std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n) const { return n * price; }
virtual void debug() const;

virtual ~Quote()
{
std::cout << "destructing Quote\n";
}

private:
std::string bookNo;

protected:
double price = 10.0;
};

bool inline
operator !=(const Quote& lhs, const Quote& rhs)
{
return lhs.bookNo != rhs.bookNo
&&
lhs.price != rhs.price;
}

#endif // QUOTE_H
59 changes: 59 additions & 0 deletions ch15/exercise15_26_2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H
#include "Disc_quote.h"
#include <iostream>

class Bulk_quote : public Disc_quote
{

public:
Bulk_quote() { std::cout << "default constructing Bulk_quote\n"; }
Bulk_quote(const std::string& b, double p, std::size_t q, double disc) :
Disc_quote(b, p, q, disc)
{
std::cout << "Bulk_quote : constructor taking 4 parameters\n";
}

// copy constructor
Bulk_quote(const Bulk_quote& bq) : Disc_quote(bq)
{
std::cout << "Bulk_quote : copy constructor\n";
}

// move constructor
Bulk_quote(Bulk_quote&& bq) : Disc_quote(std::move(bq)) noexcept
{
std::cout << "Bulk_quote : move constructor\n";
}

// copy =()
Bulk_quote& operator =(const Bulk_quote& rhs)
{
Disc_quote::operator =(rhs);
std::cout << "Bulk_quote : copy =()\n";

return *this;
}


// move =()
Bulk_quote& operator =(Bulk_quote&& rhs) noexcept
{
Disc_quote::operator =(std::move(rhs));
std::cout << "Bulk_quote : move =()\n";

return *this;
}

double net_price(std::size_t n) const override;
void debug() const override;

~Bulk_quote() override
{
std::cout << "destructing Bulk_quote\n";
}
};



#endif // BULK_QUOTE_H
Loading

0 comments on commit 6f82d41

Please sign in to comment.