第十一章:使用类
一、复习题
1.
Stonewt::Stonewt operator*(double n)
{
Stonewt temp;
temp.pounds = pounds * 14 * n;
temp.stone = (int)temp.pounds / 14;
temp.pounds_left = temp.pounds - temp.stone * 14;
return temp;
}
2. 友员函数并不是成员函数,因此不能使用对象通过.运算符来使用友员函数
3. 不一定。如果类成员均为public,则不使用友员函数也能访问类成员。
4.
Stonewt::Stonewt operator*(double n, Stonewt & s)
{
return s * n;
}
5. . :: * ?: sizeof
6. 只能在成员函数中重载他们
7.
Vector::operator double() const
{
return mag;
}
二、编程练习
1.
#ifndef C_PRIMER_CHAPTER11_VECTOR_H
#define C_PRIMER_CHAPTER11_VECTOR_H
#include <iostream>
#include <fstream>
//namespace VECTOR {
class Vector {
public:
enum Mode {
RECT, POL
};
private:
double x;
double y;
double mag;
double ang;
Mode mode;
void set_mag();
void set_ang();
void set_x();
void set_y();
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
double x_val() { return x; }
double y_val() { return y; }
double mag_val() { return mag; }
double ang_val() { return ang; }
void polar_form();
void rect_form();
Vector operator+(const Vector &b) const;
Vector operator-(const Vector &b) const;
Vector operator-() const;
Vector operator*(double n) const;
friend Vector operator*(double n, const Vector &b);
friend std::ostream &operator<<(std::ostream &os, const Vector &b);
friend std::fstream &operator<<(std::fstream &ifs, const Vector &b);
};
//}
#endif //C_PRIMER_CHAPTER11_VECTOR_H
#include "Vector.h"
#include <cmath>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
//using namespace VECTOR;
const double Rad_to_deg = 45.0 / atan(1.0);
void Vector::set_mag()
{
mag = sqrt(x * x + y * y);
}
void Vector::set_ang()
{
if(x == 0 && y == 0)
ang = 0.0;
else
ang = atan2(y,x);
}
void Vector::set_x()
{
x = mag * cos(ang);
}
void Vector::set_y()
{
y = mag * sin(ang);
}
Vector::Vector()
{
x = y = mag = ang = 0.0;
mode = RECT;
}
Vector::Vector(double n1, double n2, Mode form)
{
mode = form;
if(mode == RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else
{
mag = n1;
ang = n2 / Rad_to_deg;
set_x();
set_y();
}
}
void Vector::reset(double n1, double n2, Mode form)
{
mode = form;
if(mode == RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else
{
mag = n1;
ang = n2 / Rad_to_deg;
set_x();
set_y();
}
}
void Vector::polar_form()
{
mode = POL;
}
void Vector::rect_form()
{
mode = RECT;
}
Vector Vector::operator+(const Vector &b) const
{
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator-(const Vector &b) const
{
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator-() const
{
return Vector(-x,-y);
}
Vector Vector::operator*(double n) const
{
return Vector(n*x,n*y);
}
Vector operator*(double n, const Vector &b)
{
return b * n;
}
std::ostream & operator<<(std::ostream &os, const Vector & b)
{
if(b.mode == Vector::RECT)
os << "(x,y) = (" << b.x << ", " << b.y << ")";
else
os << "(m,a) = (" << b.mag << ", " << b.ang * Rad_to_deg << ")";
return os;
}
std::fstream &operator<<(std::fstream &ifs, const Vector &b)
{
if(b.mode == Vector::RECT)
ifs << "(x,y) = (" << b.x << ", " << b.y << ")";
else
ifs << "(m,a) = (" << b.mag << ", " << b.ang * Rad_to_deg << ")";
return ifs;
}
#include "Vector.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
using namespace std;
srand(time(0));
double direction;
Vector step;
Vector result(0.0,0.0);
unsigned long steps = 0;
double target;
double dstep;
cout << "Enter target distance (q to quit): ";
while(cin >> target)
{
cout << "Enter step length: ";
if(!(cin >> dstep))
break;
fstream ofs;
ofs.open("record");
ofs << "Target Distance: " << target << ", Step Size: " << dstep << endl;
while(result.mag_val() < target)
{
ofs << "(x,y) = (" << result.x_val() << ", " << result.y_val() << ")" << endl;
direction = rand() % 360;
step.reset(dstep,direction,Vector::POL);
result = result + step;
steps++;
}
cout << "After " << steps << " steps, the subject "
"has the following location: \n";
cout << result << endl;
result.polar_form();
cout << " or\n" << result << endl;
cout << "Average outward distance per step = "
<< result.mag_val()/steps << endl;
steps = 0;
result.reset(0.0,0.0);
cout << "Enter target distance (q to quit): ";
}
return 0;
}
2.
#ifndef C_PRIMER_CHAPTER11_VECTOR_H
#define C_PRIMER_CHAPTER11_VECTOR_H
#include <iostream>
#include <cmath>
#include <fstream>
namespace VECTOR {
class Vector {
public:
enum Mode {
RECT, POL
};
private:
double x;
double y;
//double mag;
//double ang;
Mode mode;
//void set_mag();
//void set_ang();
void set_x();
void set_y();
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
double x_val() { return x; }
double y_val() { return y; }
double mag_val() { return sqrt(x * x + y * y); }
double ang_val() {
if (x == 0 && y == 0)
return 0.0;
else
return atan2(y, x);
}
void polar_form();
void rect_form();
Vector operator+(const Vector &b) const;
Vector operator-(const Vector &b) const;
Vector operator-() const;
Vector operator*(double n) const;
friend Vector operator*(double n, const Vector &b);
friend std::ostream &operator<<(std::ostream &os, Vector b);
friend std::fstream &operator<<(std::fstream &ifs, Vector b);
};
}
#endif //C_PRIMER_CHAPTER11_VECTOR_H
#include "Vector.h"
#include <cmath>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
using namespace VECTOR;
const double Rad_to_deg = 45.0 / atan(1.0);
namespace VECTOR {
/* void Vector::set_mag() {
mag = sqrt(x * x + y * y);
}
void Vector::set_ang() {
if (x == 0 && y == 0)
ang = 0.0;
else
ang = atan2(y, x);
}
*/
void Vector::set_x() {
x = mag_val() * cos(ang_val());
}
void Vector::set_y() {
y = mag_val() * sin(ang_val());
}
Vector::Vector() {
x = y = 0.0;
mode = RECT;
}
Vector::Vector(double n1, double n2, Mode form) {
mode = form;
if (mode == RECT) {
x = n1;
y = n2;
} else {
x = n1 * cos(n2 / Rad_to_deg);
y = n1 * sin(n2 / Rad_to_deg);
}
}
void Vector::reset(double n1, double n2, Mode form) {
mode = form;
if (mode == RECT) {
x = n1;
y = n2;
} else {
x = n1 * cos(n2 / Rad_to_deg);
y = n1 * sin(n2 / Rad_to_deg);
}
}
void Vector::polar_form() {
mode = POL;
}
void Vector::rect_form() {
mode = RECT;
}
Vector Vector::operator+(const Vector &b) const {
return Vector(x + b.x, y + b.y);
}
Vector Vector::operator-(const Vector &b) const {
return Vector(x - b.x, y - b.y);
}
Vector Vector::operator-() const {
return Vector(-x, -y);
}
Vector Vector::operator*(double n) const {
return Vector(n * x, n * y);
}
Vector operator*(double n, const Vector &b) {
return b * n;
}
std::ostream &operator<<(std::ostream &os, Vector b) {
if (b.mode == Vector::RECT)
os << "(x,y) = (" << b.x << ", " << b.y << ")";
else
os << "(m,a) = (" << b.mag_val() << ", " << b.ang_val() * Rad_to_deg << ")";
return os;
}
std::fstream &operator<<(std::fstream &ifs, Vector b) {
if (b.mode == Vector::RECT)
ifs << "(x,y) = (" << b.x << ", " << b.y << ")";
else
ifs << "(m,a) = (" << b.mag_val() << ", " << b.ang_val() * Rad_to_deg << ")";
return ifs;
}
}
#include "Vector.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace VECTOR;
int main() {
using namespace std;
srand(time(0));
double direction;
Vector step;
Vector result(0.0, 0.0);
unsigned long steps = 0;
double target;
double dstep;
cout << "Enter target distance (q to quit): ";
while (cin >> target) {
cout << "Enter step length: ";
if (!(cin >> dstep))
break;
fstream ofs;
ofs.open("record");
ofs << "Target Distance: " << target << ", Step Size: " << dstep << endl;
while (result.mag_val() < target) {
ofs << "(x,y) = (" << result.x_val() << ", " << result.y_val() << ")" << endl;
direction = rand() % 360;
step.reset(dstep, direction, Vector::POL);
result = result + step;
steps++;
}
cout << "After " << steps << " steps, the subject "
"has the following location: \n";
cout << result << endl;
result.polar_form();
cout << " or\n" << result << endl;
cout << "Average outward distance per step = "
<< result.mag_val() / steps << endl;
steps = 0;
result.reset(0.0, 0.0);
cout << "Enter target distance (q to quit): ";
}
return 0;
}
3.
#include "Vector.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace VECTOR;
int main() {
using namespace std;
srand(time(0));
double direction;
Vector step;
Vector result(0.0, 0.0);
unsigned long steps = 0;
double target;
double dstep;
int tests;
cout << "Enter target distance (q to quit): ";
while (cin >> target) {
cout << "Enter step length: ";
if (!(cin >> dstep))
break;
cout << "Enter test time: ";
if(!(cin >> tests))
break;
int* parr = new int[tests];
int max = 0;
int min = 999999999;
int tot_steps = 0;
// fstream ofs;
// ofs.open("record");
// ofs << "Target Distance: " << target << ", Step Size: " << dstep << endl;
for(int i = 0;i <tests;i++) {
while (result.mag_val() < target) {
// ofs << "(x,y) = (" << result.x_val() << ", " << result.y_val() << ")" << endl;
direction = rand() % 360;
step.reset(dstep, direction, Vector::POL);
result = result + step;
steps++;
}
/*
cout << "After " << steps << " steps, the subject "
"has the following location: \n";
cout << result << endl;
result.polar_form();
cout << " or\n" << result << endl;
cout << "Average outward distance per step = "
<< result.mag_val() / steps << endl;
*/
parr[i] = steps;
if(steps > max)
max = steps;
if(steps < min)
min = steps;
tot_steps += steps;
steps = 0;
result.reset(0.0, 0.0);
}
cout << "Max steps : " << max << endl;
cout << "Min steps : " << min << endl;
cout << "Avg steps : " << (double)tot_steps/tests << endl;
delete [] parr;
cout << "Enter target distance (q to quit): ";
}
return 0;
}
4.
#ifndef C_PRIMER_CHAPTER11_TIME_H
#define C_PRIMER_CHAPTER11_TIME_H
#include <iostream>
class Time {
private:
int hours;
int minutes;
public:
Time();
explicit Time(int, int = 0);
void AddMin(int);
void AddHr(int);
void Reset(int = 0, int = 0);
friend Time operator+(const Time &a, const Time &b);
friend Time operator-(const Time &a, const Time &b);
friend Time operator*(const Time &a, double b);
friend Time operator*(double b, const Time &a);
friend std::ostream &operator<<(std::ostream &os, const Time &a);
};
#endif //C_PRIMER_CHAPTER11_TIME_H
#include "Time.h"
Time::Time() {
hours = minutes = 0;
}
Time::Time(int hr, int mins) {
hours = hr;
minutes = mins;
}
void Time::AddMin(int mins) {
minutes += mins;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHr(int hr) {
hours += hr;
}
void Time::Reset(int hr, int mins) {
hours = hr;
minutes = mins;
}
Time operator+(const Time &a, const Time &b) {
int min = a.minutes + b.minutes;
int hr = a.hours + b.hours + min / 60;
min %= 60;
return Time(hr, min);
}
Time operator-(const Time &a, const Time &b) {
int min = a.minutes - b.minutes;
int hr = a.hours - b.hours;
return Time(hr, min);
}
Time operator*(const Time &a, double b) {
long totmins = a.hours*60*b + a.minutes*b;
int min = totmins % 60;
int hr = totmins / 60;
return Time(hr, min);
}
Time operator*(double b, const Time &a) {
return a * b;
}
std::ostream &operator<<(std::ostream &os, const Time &a) {
os << a.hours << " hours, " << a.minutes << " minutes";
return os;
}
#include "Time.h"
#include <iostream>
int main()
{
using std::cout;
using std::endl;
Time aida(3,35);
Time tosca(2,48);
Time temp;
cout << "Aida and Tosca: \n";
cout << aida << "; " << tosca << endl;
temp = aida + tosca;
cout << "Aida + Tosca: " << temp << endl;
temp = aida * 1.17;
cout << "Aida * 1.17: " << temp << endl;
cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
return 0;
}
5.
#ifndef C_PRIMER_CHAPTER11_STONEWT_H
#define C_PRIMER_CHAPTER11_STONEWT_H
#include <iostream>
class Stonewt {
public:
enum Mode {
STONE, POUNDS
};
private:
enum {
Lbs_per_stn = 14
};
int stone;
double pds_left;
double pounds;
Mode mode;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
void set_Pounds();
void set_Stone();
Stonewt operator+(const Stonewt &b) const;
Stonewt operator-(const Stonewt &b) const;
Stonewt operator*(double n) const;
friend Stonewt operator*(double n, const Stonewt &b);
friend std::ostream &operator<<(std::ostream &os, const Stonewt &s);
};
#endif //C_PRIMER_CHAPTER11_STONEWT_H
#include "Stonewt.h"
Stonewt::Stonewt(double lbs) {
stone = (int) lbs / Lbs_per_stn;
pds_left = lbs - stone * Lbs_per_stn;
pounds = lbs;
mode = POUNDS;
}
Stonewt::Stonewt(int stn, double lbs) {
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
mode = STONE;
}
Stonewt::Stonewt() {
stone = pds_left = pounds = 0;
mode = POUNDS;
}
void Stonewt::set_Pounds() {
mode = POUNDS;
}
void Stonewt::set_Stone() {
mode = STONE;
}
Stonewt Stonewt::operator+(const Stonewt &b) const {
return Stonewt(pounds + b.pounds);
}
Stonewt Stonewt::operator-(const Stonewt &b) const {
return Stonewt(pounds - b.pounds);
}
Stonewt Stonewt::operator*(double n) const {
return Stonewt(pounds * n);
}
Stonewt operator*(double n, const Stonewt &b) {
return b * n;
}
std::ostream &operator<<(std::ostream &os, const Stonewt &s) {
if (s.mode == Stonewt::POUNDS) {
os << s.pounds << " pounds";
} else {
os << s.stone << " stones, " << s.pds_left << " pounds";
}
return os;
}
#include "Stonewt.h"
#include <iostream>
int main() {
using std::cout;
using std::endl;
Stonewt s1(9, 2.8);
Stonewt s2(231.7);
cout << "s1: " << s1 << ", s2: " << s2 << endl;
cout << "s1 + s2: " << s1 + s2 << endl;
cout << "s2 - s1: " << s2 - s1 << endl;
cout << "1.5 * s1: " << 1.5 * s1 << endl;
cout << "s2 * 2.5: " << s2 * 2.5 << endl;
s2.set_Stone();
cout << "another version of s2: " << s2 << endl;
s1.set_Pounds();
cout << "another version of s1: " << s1 << endl;
return 0;
}
6.
#ifndef C_PRIMER_CHAPTER11_STONEWT_H
#define C_PRIMER_CHAPTER11_STONEWT_H
#include <iostream>
class Stonewt {
public:
enum Mode {
STONE, POUNDS
};
private:
enum {
Lbs_per_stn = 14
};
int stone;
double pds_left;
double pounds;
Mode mode;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
void set_Pounds();
void set_Stone();
Stonewt operator+(const Stonewt &b) const;
Stonewt operator-(const Stonewt &b) const;
Stonewt operator*(double n) const;
bool operator<(const Stonewt &b) const;
bool operator>(const Stonewt &b) const;
bool operator<=(const Stonewt &b) const;
bool operator>=(const Stonewt &b) const;
bool operator==(const Stonewt &b) const;
bool operator!=(const Stonewt &b) const;
friend Stonewt operator*(double n, const Stonewt &b);
friend std::ostream &operator<<(std::ostream &os, const Stonewt &s);
};
#endif //C_PRIMER_CHAPTER11_STONEWT_H
#include "Stonewt.h"
Stonewt::Stonewt(double lbs) {
stone = (int) lbs / Lbs_per_stn;
pds_left = lbs - stone * Lbs_per_stn;
pounds = lbs;
mode = POUNDS;
}
Stonewt::Stonewt(int stn, double lbs) {
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
mode = STONE;
}
Stonewt::Stonewt() {
stone = pds_left = pounds = 0;
mode = POUNDS;
}
void Stonewt::set_Pounds() {
mode = POUNDS;
}
void Stonewt::set_Stone() {
mode = STONE;
}
Stonewt Stonewt::operator+(const Stonewt &b) const {
return Stonewt(pounds + b.pounds);
}
Stonewt Stonewt::operator-(const Stonewt &b) const {
return Stonewt(pounds - b.pounds);
}
Stonewt Stonewt::operator*(double n) const {
return Stonewt(pounds * n);
}
bool Stonewt::operator<(const Stonewt &b) const {
return pounds < b.pounds;
}
bool Stonewt::operator>(const Stonewt &b) const {
return pounds > b.pounds;
}
bool Stonewt::operator<=(const Stonewt &b) const {
return pounds <= b.pounds;
}
bool Stonewt::operator>=(const Stonewt &b) const {
return pounds >= b.pounds;
}
bool Stonewt::operator==(const Stonewt &b) const {
return pounds == b.pounds;
}
bool Stonewt::operator!=(const Stonewt &b) const {
return pounds != b.pounds;
}
Stonewt operator*(double n, const Stonewt &b) {
return b * n;
}
std::ostream &operator<<(std::ostream &os, const Stonewt &s) {
if (s.mode == Stonewt::POUNDS) {
os << s.pounds << " pounds";
} else {
os << s.stone << " stones, " << s.pds_left << " pounds";
}
return os;
}
#include "Stonewt.h"
#include <iostream>
int main() {
using std::cout;
using std::endl;
using std::cin;
/*
Stonewt s1(9, 2.8);
Stonewt s2(231.7);
cout << "s1: " << s1 << ", s2: " << s2 << endl;
cout << "s1 + s2: " << s1 + s2 << endl;
cout << "s2 - s1: " << s2 - s1 << endl;
cout << "1.5 * s1: " << 1.5 * s1 << endl;
cout << "s2 * 2.5: " << s2 * 2.5 << endl;
s2.set_Stone();
cout << "another version of s2: " << s2 << endl;
s1.set_Pounds();
cout << "another version of s1: " << s1 << endl;
*/
Stonewt arr[6] = {{120.5},
{250.8},
{821.6}};
for (int i = 0; i < 3; i++) {
cout << "Enter the pounds you want: ";
double temp;
cin >> temp;
arr[i + 3] = Stonewt(temp);
}
Stonewt cmp(11, 0.0);
Stonewt max = arr[0];
Stonewt min = arr[0];
int count = 0;
for (int i = 0; i < 6; i++) {
if (max < arr[i]) {
max = arr[i];
}
if (min > arr[i]) {
min = arr[i];
}
if (arr[i] >= cmp) {
count++;
}
}
cout << "The biggest: " << max << endl;
cout << "The smallest: " << min << endl;
cout << "Count: " << count << endl;
return 0;
}
7.
#ifndef C_PRIMER_CHAPTER11_PLURAL_H
#define C_PRIMER_CHAPTER11_PLURAL_H
#include <iostream>
class Plural {
private:
double x;
double y;
public:
Plural();
Plural(double x, double y);
Plural operator+(const Plural &b) const;
Plural operator-(const Plural &b) const;
Plural operator*(const Plural &b) const;
Plural operator~() const;
friend Plural operator*(double n, const Plural &b);
friend std::ostream &operator<<(std::ostream &os, const Plural &b);
friend std::istream &operator>>(std::istream &is, Plural &b);
};
#endif //C_PRIMER_CHAPTER11_PLURAL_H
#include "Plural.h"
Plural::Plural() {
x = y = 0.0;
}
Plural::Plural(double x, double y) {
this->x = x;
this->y = y;
}
Plural Plural::operator+(const Plural &b) const {
return Plural(x + b.x, y + b.y);
}
Plural Plural::operator-(const Plural &b) const {
return Plural(x - b.x, y - b.y);
}
Plural Plural::operator*(const Plural &b) const {
return Plural(x * b.x - y * b.y, x * b.y + y * b.x);
}
Plural Plural::operator~() const {
return Plural(x, -y);
}
Plural operator*(double n, const Plural &b) {
return Plural(n * b.x, n * b.y);
}
std::ostream &operator<<(std::ostream &os, const Plural &b) {
os << "(" << b.x << "," << b.y << "i)";
return os;
}
std::istream &operator>>(std::istream &is, Plural &b) {
std::cout << "real: ";
if (is >> b.x) {
std::cout << "imaginary part: ";
is >> b.y;
}
return is;
}
#include "Plural.h"
#include <iostream>
using namespace std;
int main() {
Plural a(3.0, 4.0);
Plural c;
cout << "Enter a complex number (q to quit): \n";
while (cin >> c) {
cout << "c is " << c << '\n';
cout << "complex conjugate is " << ~c << '\n';
cout << "a is " << a << '\n';
cout << "a + c is " << a + c << '\n';
cout << "a - c is " << a - c << '\n';
cout << "a * c is " << a * c << '\n';
cout << "2 * c is " << 2 * c << '\n';
cout << "Enter a complex number (q to quit): \n";
}
cout << "Done!\n";
return 0;
}