设计一个类的思路
有一个点类point,具有两个实数坐标,希望主程序使用这个类完成一下功能:
1.主程序为类point申请10个连续的存储空间
2.调用一个函数Set()从键盘输入10个对象的属性,并顺序存入申请的内存中
3.调用一个函数Display()显示10个对象的值
4.调用一个函数Length(),计算将这些点连成一条折线时,这条折线的长度
5.程序结束时,删除申请的内存
6.演示析构函数(动态对象或堆对象)的执行顺序
***************************************************************
1.类的设计思路
(1) point类有俩个哪个属性:
double x,y;
(2)求长度时需要得到两个属性值,要设计两个成员函数:
double Getx();
double Gety();
(3)因为申请了连续内存之后,才为对象赋值,所以需要一个赋值函数:
void setxy(double,double);
(4)为方便可以只设计一个构造函数,但让他有两个默认参数:
point(double=0,double=0);
(5)为了演示析构顺序,需要析构函数~point();
point类声明如下:
class point
{
public:
point(double = 0, double = 0);
double Getx();
double Gety();
void setxy(double,double);
private:
double x;
double y;
};
2.主程序设计思路
int main()
{
申请10个保存point对象的内存
调用Set输入数据
调用Display显示数据
调用Length求折线长度
释放内存
return 0;
}
(1)申请10个保存point对象的内存
假设申请一个对象,可以使用point的指针p产生:
point *p=new point(1.1,2,2);
new运算将返回动态对象(堆对象)的指针,堆对象没有名字,通过指针访问。因为成员函数是公共的,
不属于地址分配范畴,所以实际上就是为数据成员分配内存,这有两个double数据,故每个对象需要16
字节。连续分配10个对象,就需要160字节,使用如下语句:
point *p=new point[10];
这种动态分配只是给10个对象的数据成员分配存储地址,并不给各个对象命名,可以将一个对象指针
指向这块地址,通过指针使用+1或-1运算,就可以使指针向前或向后移动16个字符,从而实现存取指定
数据的目的。
由于类被看作一个数据类型2,因此使用new建立动态对象使new和构造函数一起作用。计算机首先分配
保存这个对象数据成员所需的内存,然后自动调用构造函数来初始化这段内存,再返回动态对象的地址
(2)释放内存
主程序代码如下:
int main()
{
point *p = new point[10];
if (p == NULL)
{
cout << "error" << endl;
return 0;
}
Set(p);
Display(p);
cout << Length(p) << endl;
delete[] p;
return 0;
}
3.设计其他函数
(1)Set函数
如果设计成返回指针的函数,具有如下形式:
point*Set(point *p) //动态对象指针做函数参数及返回值
{
double a, b;
int i = 0;
for ( i = 0; i < 10; i++, p++) //通过p的移动寻找下一个存储地址
{
cin >> a >> b;
p->setxy(a, b); //通过对象指针调用成员函数
}
p = p - i + 1;//返回起始地址
return p;
}
可以不用移动指针,而使用(p+i)寻找下一个存储地址,这样就不需要
返回存储的起始地址,从而将其简化为void函数:
void Set(point *p)
{
double a, b;
int i = 0;
for ( i = 0; i < 10; i++) //通过p的移动寻找下一个存储地址
{
cin >> a >> b;
(p+i)->setxy(a, b); //通过对象指针调用成员函数
}
}
(2)Display函数:
void Display(point *p)
{
for (int i = 0; i < num; i++)
cout << (p + i)->Getx() << "," << (p + i)->Gety() << endl;
}
(3)Length函数
Length函数需要使用一对变量保存第一个点的坐标值,然后用一对变量保存
第二个点的坐标值,求出线段长度时,需要将这两个变量依次向后平移。
继续上述过程并累计线段长度为折线长度,结束返回计算结果
double Length(point *p)
{
double sum(0.0), a1, b1, a2, b2;
a1 = p->Getx();
b1 = p->Gety();
for (int i = 1; i < 10; i++)
{
a2 = (p + i)->Getx();
b2 = (p + i)->Gety();
sum += sqrt((a1 - a2)*(a1 - a2) + (b1 - b2)(b1 - b2));
a1 = a2;
b1 = b2;
}
return sum;
}
代码:
#include "stdafx.h"
#include<iostream>
using namespace std;
class point
{
public:
point( double = 0, double = 0);
double Getx();
double Gety();
void setxy(double ,double);
~point();
private:
double x;
double y;
};
point::point(double a, double b)
{
x = a;
y = b;
}
double point ::Getx()
{
return x;
}
double point ::Gety()
{
return y;
}
void point ::setxy(double a, double b)
{
x = a;
y = b;
}
point::~point()
{
cout << "delete it:" << x << "," << y << endl;
}
const int num = 10;
void Set(point *p)
{
double a, b;
for (int i = 0; i < num; i++)
{
cout << "input 第" << i + 1 << "个对象的两个数据成员的值:" ;
cin >> a >> b;
( p + i)->setxy(a, b);
}
}
void Display(point *p)
{
for (int i = 0; i < num; i++)
cout << (p + i)->Getx() << "," << (p + i)->Gety() << endl;
}
double Length(point *p)
{
double sum(0.0), a1, b1, a2, b2;
a1 = p->Getx();
b1 = p->Gety();
for (int i = 1; i < 10; i++)
{
a2 = ( p + i)->Getx();
b2 = ( p + i)->Gety();
sum += sqrt((a1 - a2)*(a1 - a2) + (b1 - b2)*(b1 - b2));
a1 = a2;
b1 = b2;
}
return sum;
}
int main()
{
point *p = new point[10];
if (p == NULL )
{
cout << "error" << endl;
return 0;
}
Set(p);
Display(p);
cout << Length(p) << endl;
delete[] p;
system( "pause");
return 0;
}