摘要: 阅读全文
这是一个定义的一个矢量类, 然后用矢量类模拟一个酒鬼的随机漫步
问题很简单, 实现也不麻烦, 但是这个小程序却可以呈现出许多语法知识。而且代码风格也不错,因此保存在了这篇博客中。
建议:
1. 类的声明以及函数的声明放到一个文件夹内, 并且在一些必要的地方加上注释!
2. 函数的实现放到另一个文件内。
3. 将程序要具体解决的问题放到另外的一个文件里。(详见代码!)
好处: 把类的接口和实现细节分离开, 易于更改某个函数的功能。
把函数的声明和定义分开, 提高代码可读性。
把类的声明和定义 与 要解决的问题分开, 提高,类的重用性!
定义类(声明类内的函数)
// vect.h -- Vector class with <<, mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR
{
class Vector
{
public:
enum Mode{RECT, POL};
// RECT for rectangular, POL for Polar modes
private:
double x; // horizontal value
double y; // vertical value
double mag; // length of vector in degrees
double ang;// direction of vector in degrees
Mode mode; // private methods for setting values
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; } // report x value
double yval() const {return y; } // report y value
double magval() const {return mag; } // report magnitude
double angval() const {return ang; } // report angle
void polar_mode(); // set mode to POL
void rect_mode(); // set mode to RECT
// operator overloading
Vector operator+(const Vector & b) const;
Vector operator-(const Vector & b) const;
Vector operator-()const;
Vector operator*(double n) const;
// friends
friend Vector operator*(double n, const Vector & a);
friend std::ostream & operator<<(std::ostream & os, const Vector & v);
};
} // end namespace VECTOR
#endif
上面代码涵盖了许多关于类的基础知识: 名称空间与作用域 , 实现类内部常量的方法, 构造函数, 析构函数, 运算符重载, 友元函数, 关于多种实现方法等。
PS: 实现类内部常量的方法: (1)枚举类型。 (2) static const int 常量
运算符重载: 注意操作数的顺序。
函数定义
// vect.cpp -- methods for the Vector class
#include <cmath>
#include "vect.h" // include <iostream>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
namespace VECTOR
{
// compute degree in one radian
const double Rad_to_deg = 45.0/atan(1.0);
// should be about 57.2957795130823
// private methods
// calculate magnitude from x and y
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);
}
//set x from polar coordinate
void Vector::set_x()
{
x = mag*cos(ang);
}
//set y from polar coodinate
void Vector::set_y()
{
y = mag * sin(ang);
}
// public methods
Vector::Vector() // default constructor
{
x = y = mag = ang = 0.0;
mode = RECT;
}
// construct vector from rectangular coordinates if form is r
// (the default) or else from polar coordinates if form is p
Vector::Vector(double n1, double n2, Mode form)
{
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
{
cout << "Incorrect 3rd argument to Vector() --";
cout << "vector set to 0.0";
mode = RECT;
}
}
// reset vector from rectangular coodinates if form is
// RECT (the default) or else form polar coordinates if
// form is POL
void Vector::reset(double n1, double n2, Mode form)
{
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
{
cout << "Incorrect 3rd argument to Vector() -- ";
cout <<"vector set to 0.0n";
x = y = mag = ang = 0.0;
mode = RECT;
}
}
Vector::~Vector() // destructor
{
}
void Vector::polar_mode() //set to polar mode
{
mode = POL;
}
void Vector::rect_mode()// set to rectangular mode
{
mode = RECT;
}
// operator overloading
// add two Vectors
Vector Vector::operator+(const Vector & b) const
{
return Vector(x + b.x, y + b.y);
}
//subtract Vector b from a
Vector Vector::operator-(const Vector & b) const
{
return Vector(x-b.x, y-b.y);
}
// reverse sign of Vector
Vector Vector::operator-() const
{
return Vector(-x, -y);
}
// multiply vector by n
Vector Vector::operator*(double n) const
{
return Vector(n*x, n*y);
}
// friend methods
// multiply n by Vector a
Vector operator*(double n, const Vector & a)
{
return a * n;
}
//display rectangular coordinates if mode is RECT
// else display polar coordinates if mode is POL
std::ostream & 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;
}
} // end namespace VECTOR
具体解决的问题
// randwalk.cpp -- using the Vector class
// compile with the vect.cpp file
#include <iostream>
#include <cstdlib> // rand(), srand() pototypes
#include <ctime> // time() pototype
#include "vect.h"
int main()
{
using namespace std;
using VECTOR::Vector;
srand(time(0)); // seed random-number generator
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;
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 << "orn" << result << endl;
cout << "Average outward distance per step = "
<< result.magval()/steps << endl;
steps = 0;
result.reset(0.0, 0.0);
cout << "Enter target distance (q to quit): ";
}
cout << "Bye!n";
cin.clear();
while(cin.get() != 'n')
continue;
return 0;
}
二。一个简易的string类。
锻炼内容:
拷贝构造函数(深拷贝与浅拷贝)
重载赋值运算符(深赋值)
许多的细节与技巧!
类的声明
//sting1.h -- fixed and augmented string class definition
#ifndef STRING1_H_
#define STRING1_H_
#include <iostream>
using std::ostream;
using std::istream;
class String
{
private:
char * str; // pointer ot string
int len; // length of string
static int num_strings; // number of objects
static const int CINLIM = 80; // cin input limit
public:
// construction and other methods
String(const char * s); // constructor
String(); // default constructor
String(const String &); // copy constructor
~String(); // destructor
int length() const { return len; }
// overloaded operator methods
String & operator=(const String &);
String & operator=(const char *);
char & operator[](int i);
const char & operator[](int i)const;
// overloaded operator friends
friend bool operator<(const String &st, const String &st2);
friend bool operator>(const String &st1, const String &st2);
friend bool operator==(const String &st, const String &st2);
friend ostream & operator<<(ostream & os, const String & st);
friend istream & operator>>(istream & is, String & st);
//static function
static int HowMany();
};
#endif
View Code
类方法的实现。
// string1.cpp -- String class methods
#include <cstring> // string.h for some
#include "string1.h" // includes <iostream>
using std::cin;
using std::cout;
// initializing static class member
int String::num_strings = 0;
// static method
int String::HowMany()
{
return num_strings;
}
// class methods
String::String(const char * s) // construct String from C string
{
len = std::strlen(s); // set size
str = new char[len + 1]; // allot storage
std::strcpy(str, s); // initialize pointer
num_strings++; // set object count
}
String::String() // default constructor
{
len = 4;
str = new char[1];
str[0] = ' '; // default string
num_strings++;
}
String::String(const String & st)
{
num_strings++; // handle static member update
len = st.len; // same length
str = new char [len + 1]; // allot space
std::strcpy(str, st.str); // copy string to new location
}
String::~String() // necesserary destructor
{
--num_strings; // required
delete [] str; // required
}
// overloaded operator methods
// assign a String to a String
String & String::operator=(const String & st)
{
if(this == &st)
return *this;
delete [] str;
len = st.len;
str = new char[len + 1];
std::strcpy(str, st.str);
return *this;
}
// assign a C string to a String
String & String::operator=(const char * s)
{
delete [] str;
len = std::strlen(s);
str = new char[len + 1];
std::strcpy(str, s);
return *this;
}
// read-write char access for non-const String
char & String::operator[](int i)
{
return str[i];
}
// read-only char access for const string
const char & String::operator[](int i) const
{
return str[i];
}
// averloaded operator friends
bool operator<(const String &st1, const String &st2)
{
return (std::strcmp(st1.str, st2.str) < 0);
}
bool operator>(const String &st1, const String &st2)
{
return st2 < st1;
}
bool operator==(const String &st1, const String &st2)
{
return (std::strcmp(st1.str, st2.str)==0);
}
// simple String output
ostream & operator<<(ostream & os, const String & st)
{
os << st.str;
return os;
}
// quick and dirty String input
istream & operator>>(istream & is, String & st)
{
char temp[String::CINLIM];
is.get(temp, String::CINLIM);
if(is)
st = temp;
while (is && is.get() != 'n')
continue;
return is;
}
View Code
main(), 测试String类。
// saying1.cpp -- using expanded String class
// complile with string1.cpp
#include <iostream>
#include "string1.h"
const int MaxLen = 81;
int main()
{
using std::cout;
using std::cin;
using std::endl;
String name;
cout << "Hi, what's your name?n>> ";
cin >> name;
cout << name << ", please enter up to " << ArSize
<< " short sayings <empty line to quit>:n";
String sayings[ArSize]; // array of objects
char temp[MaxLen] // temporary string storage
int i;
for (i = 0; i < ArSize; i++)
{
cout << i + 1 << ": ";
cin.get(temp, MaxLen);
while(cin && cin.get()!='n')
continue;
if(!cin||temp[0] == ' ') // empty line?
break; // i not increamented
else
sayings[i] = temp; // overloaded assignment
}
int total = i; // total # of lines read
if( total > 0)
{
cout << "Here are your sayings:n";
for (i = 0; i < total; i++)
cout << sayings[i][0] << ": " << sayings[i] << endl;
int shortest = 0;
int first = 0;
for(i = 1; i < total; i++)
{
if(sayings[i].length() < sayings[shortest].length())
shortest = i;
if(sayings[i] < sayings[first])
first = i;
}
cout << "Shortest saying:n" << sayings[shortest] << endl;
cout << "First alphabetically:n" << sayings[first] << endl;
cout << "This program used " << String::HowMany()
<< " String objects. Bye.n"
}
else
cout << "No input! Bye.n";
return 0;
}
View Code
代码源自: C++ Primer Plus 。 小恪亲自敲写!
感悟: 如果一部书经久不衰, 一定是有它的理由的! 正如这部书, 内容细致而深刻, 全面而严谨。获益良多!此书有点儿厚,与诸君共勉。
原文链接: https://www.cnblogs.com/acm1314/p/4854000.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/222636
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!