c++primer学习笔记4(11章后+12章前)

时隔好多天继续学习。

在什么都不设置的情况下,如果构造函数中存在只需一个参数就可以初始化的函数,那么"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;
}

那么今天就看到这里,明天继续。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值