这章主要讲重载运算符,友元函数和类型转换。
1.话说题目说的程序清单11.5,应该是错了吧,应该是11.15吧。
第一题就困了我好久,怎么都访问不了私有成员,一开始以为是哪里写错了,对着书敲代码都不行。
后来又觉得会不会友元的重载运算符太复杂,就自己写个简单的友元函数,发现也不行。
在main函数里面调用发现可以变得过,但是链接的时候才发现居然链接不上。
这个时候才想到我使用了using namespace xxx。但是对于类外的函数,是链接不上的,还是需要加上namespace。
原来的代码:
Test.h
//
// Test.h
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#ifndef _Test_H_
#define _Test_H_
#include <iostream>
namespace FableGame
{
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);
~Vector();
double xval() const { return x; }
double yval() const { return y; }
double magval() const { return mag; }
double angval() const { return ang; }
void polar_mode();
void rect_mode();
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& a);
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
};
}
#endif
Test.cpp
//
// Test.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include "Test.h"
#include <iostream>
#include <cmath>
using namespace FableGame;
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.0 && y == 0.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 /*= RECT*/)
{
reset(n1, n2, form);
}
void Vector::reset(double n1, double n2, Mode form /*= RECT*/)
{
mode = form;
if (form == RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else if (form == POL)
{
mag = n1;
ang = n2 / Rad_to_deg;
set_x();
set_y();
}
else
{
std::cout << "Incorrect 3rd grgument to Vector() -- ";
std::cout << "vector set to 0\n";
x = y = mag = ang = 0.0;
mode = RECT;
}
}
Vector::~Vector()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
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 FableGame::operator*(double n, const Vector& a)
{
return a * n;
}
std::ostream& FableGame::operator<<(std::ostream& os, const Vector& v)
{
if (v.mode == Vector::RECT)
{
os << "(x,y) = (" << v.x << ", " << v.y << ")";
}
else if (v.mode == Vector::POL)
{
os << "(m,a) = (" << v.mag << ", " << v.ang * Rad_to_deg << ")";
}
else
{
os << "Vector object mode is invalid";
}
return os;
}
main.cpp
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Test.h"
using namespace std;
using namespace FableGame;
int main()
{
srand(time_t(0));//设置随机数种子
double direction;//方向
Vector step;//新的一步
Vector result(0,0);//当前位置
int steps = 0;//步数
double target;//目标距离
double dstep;//每一步的距离
cout << "Enter target distance (q to quit): ";
while (cin >> target) {
cout << "Enter step length: ";
if (!(cin>> dstep)) {
break;
}
while(result.magval() < target)
{
//离起点的距离还没达到目标距离,就要继续执行
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_mode();
cout << " or\n" << result << endl;
cout << "Average outward distance per step = "
<< result.magval()/steps << endl;
steps = 0;
result.reset(0, 0);
cout << "Enter target distance (q to quit): ";
}
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n') {
continue;
}
return 0;
}
回家用xcode再写一次,发现怎么都链接不了,最后发现在xcode里面手动改文件名导致识别不了文件的。
再看看更改后的:
只改main.cpp就行了
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Test.h"
#include <fstream>
using namespace std;
using namespace FableGame;
int main()
{
ofstream of;//声明一个输出的对象
of.open("/Users/feiyin001/Documents/myTest.txt");//打开文件
srand(time_t(0));//设置随机数种子
double direction;//方向
Vector step;//新的一步
Vector result(0,0);//当前位置
int steps = 0;//步数
double target;//目标距离
double dstep;//每一步的距离
cout << "Enter target distance (q to quit): ";
while (cin >> target) {
cout << "Enter step length: ";
if (!(cin>> dstep)) {
break;
}
of << "Target Distance: " << target <<", Step Size: " << dstep<<endl;
of << 0 << ": " << result << endl;
while(result.magval() < target)
{
//离起点的距离还没达到目标距离,就要继续执行
direction = rand() % 360;//随机一个方向,角度
step.reset(dstep, direction, Vector::POL);//当前的一步
result = result + step;//当前的实际位置
steps++;//计数
of << steps << ": " << result << endl;
}
of << "After " << steps << " steps, the subject has the following location:\n";
of << result <<endl;
result.polar_mode();
of << " or\n" << result << endl;
of << "Average outward distance per step = "
<< result.magval()/steps << endl;
steps = 0;
result.reset(0, 0);
cout << "Enter target distance (q to quit): ";
}
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n') {
continue;
}
of.close();
return 0;
}
顺便看看结果吧:
Target Distance: 100, Step Size: 20
0: (x,y) = (0, 0)
1: (x,y) = (17.3205, -10)
2: (x,y) = (29.9069, 5.54292)
3: (x,y) = (28.1638, 25.4668)
4: (x,y) = (15.8506, 9.7066)
5: (x,y) = (6.15438, -7.7858)
6: (x,y) = (21.6973, -20.3722)
7: (x,y) = (41.3935, -16.8992)
8: (x,y) = (25.4207, -28.9355)
9: (x,y) = (41.181, -16.6223)
10: (x,y) = (30.8802, 0.521035)
11: (x,y) = (48.8561, -8.24639)
12: (x,y) = (45.3831, -27.9425)
13: (x,y) = (46.7782, -7.99126)
14: (x,y) = (62.9586, 3.76444)
15: (x,y) = (62.9586, 23.7644)
16: (x,y) = (62.2606, 3.77663)
17: (x,y) = (52.5644, 21.269)
18: (x,y) = (68.9474, 9.79749)
19: (x,y) = (87.2184, 17.9322)
20: (x,y) = (98.9741, 34.1126)
After 20 steps, the subject has the following location:
(x,y) = (98.9741, 34.1126)
or
(m,a) = (104.688, 19.0171)
Average outward distance per step = 5.23439
2.为了尽量保持原形,随时还原,我还是尽量用注释吧。
Test.h
//
// Test.h
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#ifndef _Test_H_
#define _Test_H_
#include <iostream>
namespace FableGame
{
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(double mag, double ang);
void set_y(double mag, double ang);
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
~Vector();
double xval() const { return x; }
double yval() const { return y; }
double magval() const;
double angval() const;
void polar_mode();
void rect_mode();
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& a);
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
};
}
#endif
Test.cpp
//
// Test.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include "Test.h"
#include <iostream>
#include <cmath>
using namespace FableGame;
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.0 && y == 0.0)
// {
// ang = 0.0;
// }
// else
// {
// ang = atan2(y, x);
// }
//}
double Vector::angval() const
{
double ang;
if (x == 0.0 && y == 0.0)
{
ang = 0.0;
}
else
{
ang = atan2(y, x);
}
return ang;
}
double Vector::magval() const
{
double mag = sqrt(x*x + y*y);
return mag;
}
void Vector::set_x(double mag, double ang)
{
x = mag * cos(ang);
}
void Vector::set_y(double mag, double ang)
{
y = mag * sin(ang);
}
Vector::Vector()
{
//x = y = mag = ang = 0.0;
x = y = 0;
mode = RECT;
}
Vector::Vector(double n1, double n2, Mode form /*= RECT*/)
{
reset(n1, n2, form);
}
void Vector::reset(double n1, double n2, Mode form /*= RECT*/)
{
mode = form;
if (form == RECT)
{
x = n1;
y = n2;
//set_mag();
//set_ang();
}
else if (form == POL)
{
double mag = n1;
double ang = n2 / Rad_to_deg;
set_x(mag, ang);
set_y(mag, ang);
}
else
{
std::cout << "Incorrect 3rd grgument to Vector() -- ";
std::cout << "vector set to 0\n";
//x = y = mag = ang = 0.0;
x = y = 0;
mode = RECT;
}
}
Vector::~Vector()
{
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
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 FableGame::operator*(double n, const Vector& a)
{
return a * n;
}
std::ostream& FableGame::operator<<(std::ostream& os, const Vector& v)
{
if (v.mode == Vector::RECT)
{
os << "(x,y) = (" << v.x << ", " << v.y << ")";
}
else if (v.mode == Vector::POL)
{
os << "(m,a) = (" << v.magval() << ", " << v.angval() * Rad_to_deg << ")";
}
else
{
os << "Vector object mode is invalid";
}
return os;
}
3.保留了文件输出,不改回来了。
//
// main.cpp
// HelloWorld
//
// Created by feiyin001 on 16/12/21.
// Copyright (c) 2016年 FableGame. All rights reserved.
//
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Test.h"
#include <fstream>
using namespace std;
using namespace FableGame;
int main()
{
ofstream of;//声明一个输出的对象
of.open("/Users/feiyin001/Documents/myTest.txt");//打开文件
srand(time_t(0));//设置随机数种子
double direction;//方向
Vector step;//新的一步
Vector result(0,0);//当前位置
int steps = 0;//步数
double target;//目标距离
double dstep;//每一步的距离
cout << "Enter target distance (q to quit): ";
while (cin >> target) {
cout << "Enter step length: ";
if (!(cin>> dstep)) {
break;
}
of << "Target Distance: " << target <<", Step Size: " << dstep<<endl;
int num = 0;//测试次数
cout << "Enter Test Times: ";//输入测试次数
if (!(cin>> num) || num < 0) {
break;
}
int maxSteps = 0;
int minSteps = 0;
int totalSteps = 0;
for (int i = 0; i < num; ++i) {
of << 0 << ": " << result << endl;
while(result.magval() < target)
{
//离起点的距离还没达到目标距离,就要继续执行
direction = rand() % 360;//随机一个方向,角度
step.reset(dstep, direction, Vector::POL);//当前的一步
result = result + step;//当前的实际位置
steps++;//计数
of << steps << ": " << result << endl;
}
of << "After " << steps << " steps, the subject has the following location:\n";
of << result <<endl;
result.polar_mode();
of << " or\n" << result << endl;
of << "Average outward distance per step = "
<< result.magval()/steps << endl;
if (i == 0) {
totalSteps = minSteps = maxSteps = steps;
}
else{
totalSteps += steps;
if (minSteps > steps) {
minSteps = steps;
}
if (maxSteps < steps) {
maxSteps = steps;
}
}
steps = 0;
result.reset(0, 0);
}
of << "Test Times: " << num << " average steps: "<< totalSteps / num << endl;
of << "max steps: " << maxSteps << " min steps: " << minSteps << endl;
cout << "Enter target distance (q to quit): ";
}
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n') {
continue;
}
of.close();
return 0;
}