Skip to content

Commit

Permalink
粗略完成第十五章
Browse files Browse the repository at this point in the history
  • Loading branch information
ShujiaHuang committed Aug 15, 2021
1 parent 5536026 commit b626d5b
Show file tree
Hide file tree
Showing 22 changed files with 1,139 additions and 0 deletions.
41 changes: 41 additions & 0 deletions practice/booknotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4454,3 +4454,44 @@ C++提供了几种重用代码的手段。无论使用哪种继 承,基类的
多重继承(MI)使得能够在类设计中重用多个类的代码。
# 第十五章 友元、异常和其他
本章内容包括:
- 友元类;
- 友元类方法;
- 嵌套类;
- 引发异常、`try`块和`catch`块;
- 异常类;
- 运行阶段类型识别(RTTI);
- `dynamic_cast` 和 `typeid`;
- `static_cast`、`const_cast` 和 `reiterpret_cast`。
![image-20210815204948714](https://static.fungenomics.com/images/2021/08/image-20210815204948714.png)
2.bad_alloc异常和new
对于使用new导致的内存分配问题,C++的**最新处理方式是让new引发bad_alloc异常**。头文件new包含bad_alloc类的声明,它是从exception 类公有派生而来的。但**在以前,当无法分配请求的内存量时,new返回 一个空指针**,然后我们可以 `exit(EXIT_FAILURE)`。
## 15.6 总结
友元使得能够为类开发更灵活的接口。类可以将其他函数、其他类 和其他类的成员函数作为友元。在某些情况下,可能需要使用前向声 明,需要特别注意类和方法声明的顺序,以正确地组合友元。
嵌套类是在其他类中声明的类,它有助于设计这样的助手类,即实 现其他类,但不必是公有接口的组成部分。
28 changes: 28 additions & 0 deletions source/chapter15/constcast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// constcast.cpp -- using const_cast<>
#include <iostream>
using std::cout;
using std::endl;

void change(const int * pt, int n);

int main()
{
int pop1 = 38383;
const int pop2 = 2000;

cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;
change(&pop1, -103);
change(&pop2, -103);
cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;
// std::cin.get();
return 0;
}

void change(const int * pt, int n)
{
int * pc;

pc = const_cast<int *>(pt);
*pc += n;

}
30 changes: 30 additions & 0 deletions source/chapter15/error1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//error1.cpp -- using the abort() function
#include <iostream>
#include <cstdlib>
double hmean(double a, double b);

int main()
{
double x, y, z;

std::cout << "Enter two numbers: ";
while (std::cin >> x >> y)
{
z = hmean(x,y);
std::cout << "Harmonic mean of " << x << " and " << y
<< " is " << z << std::endl;
std::cout << "Enter next set of numbers <q to quit>: ";
}
std::cout << "Bye!\n";
return 0;
}

double hmean(double a, double b)
{
if (a == -b)
{
std::cout << "untenable arguments to hmean()\n";
std::abort();
}
return 2.0 * a * b / (a + b);
}
38 changes: 38 additions & 0 deletions source/chapter15/error2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//error2.cpp -- returning an error code
#include <iostream>
#include <cfloat> // (or float.h) for DBL_MAX

bool hmean(double a, double b, double * ans);

int main()
{
double x, y, z;

std::cout << "Enter two numbers: ";
while (std::cin >> x >> y)
{
if (hmean(x,y,&z))
std::cout << "Harmonic mean of " << x << " and " << y
<< " is " << z << std::endl;
else
std::cout << "One value should not be the negative "
<< "of the other - try again.\n";
std::cout << "Enter next set of numbers <q to quit>: ";
}
std::cout << "Bye!\n";
return 0;
}

bool hmean(double a, double b, double * ans)
{
if (a == -b)
{
*ans = DBL_MAX;
return false;
}
else
{
*ans = 2.0 * a * b / (a + b);
return true;
}
}
34 changes: 34 additions & 0 deletions source/chapter15/error3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// error3.cpp -- using an exception
#include <iostream>
double hmean(double a, double b);

int main()
{
double x, y, z;

std::cout << "Enter two numbers: ";
while (std::cin >> x >> y)
{
try { // start of try block
z = hmean(x,y);
} // end of try block
catch (const char * s) // start of exception handler
{
std::cout << s << std::endl;
std::cout << "Enter a new pair of numbers: ";
continue;
} // end of handler
std::cout << "Harmonic mean of " << x << " and " << y
<< " is " << z << std::endl;
std::cout << "Enter next set of numbers <q to quit>: ";
}
std::cout << "Bye!\n";
return 0;
}

double hmean(double a, double b)
{
if (a == -b)
throw "bad hmean() arguments: a = -b not allowed";
return 2.0 * a * b / (a + b);
}
60 changes: 60 additions & 0 deletions source/chapter15/error4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//error4.cpp – using exception classes
#include <iostream>
#include <cmath> // or math.h, unix users may need -lm flag
#include "exc_mean.h"
// function prototypes
double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
using std::cout;
using std::cin;
using std::endl;

double x, y, z;

cout << "Enter two numbers: ";
while (cin >> x >> y)
{
try { // start of try block
z = hmean(x,y);
cout << "Harmonic mean of " << x << " and " << y
<< " is " << z << endl;
cout << "Geometric mean of " << x << " and " << y
<< " is " << gmean(x,y) << endl;
cout << "Enter next set of numbers <q to quit>: ";
}// end of try block
catch (bad_hmean & bg) // start of catch block
{
bg.mesg();
cout << "Try again.\n";
continue;
}
catch (bad_gmean & hg)
{
cout << hg.mesg();
cout << "Values used: " << hg.v1 << ", "
<< hg.v2 << endl;
cout << "Sorry, you don't get to play any more.\n";
break;
} // end of catch block
}
cout << "Bye!\n";
// cin.get();
// cin.get();
return 0;
}

double hmean(double a, double b)
{
if (a == -b)
throw bad_hmean(a,b);
return 2.0 * a * b / (a + b);
}

double gmean(double a, double b)
{
if (a < 0 || b < 0)
throw bad_gmean(a,b);
return std::sqrt(a * b);
}
106 changes: 106 additions & 0 deletions source/chapter15/error5.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//error5.cpp -- unwinding the stack
#include <iostream>
#include <cmath> // or math.h, unix users may need -lm flag
#include <string>
#include "exc_mean.h"

class demo
{
private:
std::string word;
public:
demo (const std::string & str)
{

word = str;
std::cout << "demo " << word << " created\n";
}
~demo()
{
std::cout << "demo " << word << " destroyed\n";
}
void show() const
{
std::cout << "demo " << word << " lives!\n";
}
};

// function prototypes
double hmean(double a, double b);
double gmean(double a, double b);
double means(double a, double b);

int main()
{
using std::cout;
using std::cin;
using std::endl;

double x, y, z;
{
demo d1("found in block in main()");
cout << "Enter two numbers: ";
while (cin >> x >> y)
{
try { // start of try block
z = means(x,y);
cout << "The mean mean of " << x << " and " << y
<< " is " << z << endl;
cout << "Enter next pair: ";
} // end of try block
catch (bad_hmean & bg) // start of catch block
{
bg.mesg();
cout << "Try again.\n";
continue;
}
catch (bad_gmean & hg)
{
cout << hg.mesg();
cout << "Values used: " << hg.v1 << ", "
<< hg.v2 << endl;
cout << "Sorry, you don't get to play any more.\n";
break;
} // end of catch block
}
d1.show();
}
cout << "Bye!\n";
// cin.get();
// cin.get();
return 0;
}

double hmean(double a, double b)
{
if (a == -b)
throw bad_hmean(a,b);
return 2.0 * a * b / (a + b);
}

double gmean(double a, double b)
{
if (a < 0 || b < 0)
throw bad_gmean(a,b);
return std::sqrt(a * b);
}

double means(double a, double b)
{
double am, hm, gm;
demo d2("found in means()");
am = (a + b) / 2.0; // arithmetic mean
try
{
hm = hmean(a,b);
gm = gmean(a,b);
}
catch (bad_hmean & bg) // start of catch block
{
bg.mesg();
std::cout << "Caught in means()\n";
throw; // rethrows the exception
}
d2.show();
return (am + hm + gm) / 3.0;
}
32 changes: 32 additions & 0 deletions source/chapter15/exc_mean.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// exc_mean.h -- exception classes for hmean(), gmean()
#include <iostream>

class bad_hmean
{
private:
double v1;
double v2;
public:
bad_hmean(double a = 0, double b = 0) : v1(a), v2(b){}
void mesg();
};

inline void bad_hmean::mesg()
{
std::cout << "hmean(" << v1 << ", " << v2 <<"): "
<< "invalid arguments: a = -b\n";
}

class bad_gmean
{
public:
double v1;
double v2;
bad_gmean(double a = 0, double b = 0) : v1(a), v2(b){}
const char * mesg();
};

inline const char * bad_gmean::mesg()
{
return "gmean() arguments should be >= 0\n";
}
Loading

0 comments on commit b626d5b

Please sign in to comment.