时隔好多天继续学习。
在什么都不设置的情况下,如果构造函数中存在只需一个参数就可以初始化的函数,那么"class object=1;"就可以成立,这在一些情况中可能产生问题,可以在构造函数前声明explicit关闭这个自动特性。
而如果想"int a=object"也可以,这就需要使用转换函数。
operator int()const{
return ...;
}
增加了c++类使用的灵活性和复杂性。。。
写一下编程练习第一题,可以练习到很多东西:文件流、命名空间、运算符重载、随机。
// randwalk.cpp
#include "stdafx.h"
#include "vector.h"
#include <cstdlib>
#include <ctime>
#include <fstream>
int main()
{
using std::cout;
using std::cin;
using std::endl;
using namespace VECTOR;
srand(time(0));
std::ofstream outFile;
outFile.open("randwalk.txt");//默认自动创建覆盖式写入
int target, size, num;
cout << "Please enter the Target Distance:";
cin >> target;
cout << "Please enter the Step Size:";
cin >> size;
cout << "Please enter the number of tests:";
cin >> num;
cout << "Target Distance=" << target << " Step Size=" << size << endl;
cout << "number=" << num << endl << endl;
outFile << "Target Distance=" << target << " Step Size=" << size << endl;
outFile << "number=" << num << endl << endl;
int max = 0, min = 0, average = 0;
int testn = 1;
while (testn <= num) {
cout << "Test " << testn << ":" << endl;
outFile << "Test " << testn << ":" << endl;
int n = 0;
Vector step;
do {
Vector stepn(size, rand() % 360, POL);
step = step + stepn;
n++;
cout << n << ": " << step;
outFile << n << ": " << step;
} while (step.magval() < target);
step.set_mode(POL);
cout << "Now POL address-- " << step;
outFile << "Now POL address-- " << step;
if (testn) {
average = (average + n) / 2;
if (n > max)max = n;
if (n < min)min = n;
}
else
max = min = average = n;
testn++;
}
cout << "The Max numble is:" << max << endl;
cout << "The Min numble is:" << min << endl;
cout << "The Average numble is:" << average << endl;
outFile << "The Max numble is:" << max << endl;
outFile << "The Min numble is:" << min << endl;
outFile << "The Average numble is:" << average << endl;
outFile.close();
return 0;
}
//vector.h
#pragma once
namespace VECTOR
{
enum Mode { RECT, POL };//二维坐标 极坐标
class Vector
{
private:
double x;
double y;
double mag;
double ang;
Mode mode;
public:
Vector();
Vector(double n1, double n2, Mode m);
~Vector();
void set_mode(Mode m) { mode = m; }
double xval() const { return x; }
double yval() const { return y; }
double magval() const { return mag; }
double angval() const { return ang; }
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);
};
}
//vector.cpp
#include "stdafx.h"
#include <cmath>
#include "vector.h"
namespace VECTOR
{
const double PI = 3.1415926;
Vector::Vector(){
mode = RECT;
x = y = 0.0;
mag = 0.0;
ang = 0.0;
}
Vector::Vector(double n1, double n2, Mode m=RECT){
mode = m;
if (m == RECT) {
x = n1;
y = n2;
mag= std::sqrt(x * x + y * y);
ang= std::atan2(y, x)*180/PI;
}
else if (m == POL) {
mag = n1;
ang = n2;
x = mag * std::cos(ang/180*PI);
y = mag * std::sin(ang/180*PI);
}
}
Vector::~Vector(){}
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 & a){
return a * n;
}
std::ostream & operator<<(std::ostream & os, const Vector & v){
if(v.mode==RECT)
os << "(x, y) = (" << v.x << ", " << v.y << ")" << std::endl;
else if(v.mode==POL)
os << "(m, a) = (" << v.mag << ", " << v.ang << "°)" << std::endl;
return os;
}
}
/**************************************************************************************************************************************/
然后是关于动态内存分配与类的问题。当类中存在指向new分配内存的指针成员时,如果使用默认复制构造函数,就产生问题。因为复制将产生指向同一段地址的指针,而在复制对象析构后内存跟着释放,原对象指针成员所指向的地址将为非法。如果有静态成员进行计数单纯复制也会有问题。复制构造函数的形式是 clas(const clas & c){}。
而在赋值操作时,依然会出现问题,这就需要重载赋值运算符。要先检查是否是自我复制,如果不是先释放动态内存再拷贝过来
clas & operator=(const clas &c){
if(this==&c)
return *this;
delete []p;
p=new int[c.n];
int num=0;
while(num<c.n){
p[num]=c[num];
num++;
}
return *this;
}
那么今天就看到这里,明天继续。