要求
设计一个库,提供动态实型数组服务,该数组满足两个要求
数组的存储
数组操作
头文件
#ifndef _DoubleArray_h
#define _DoubleArray_h
struct DoubleArray //可指定下标范围的数组的存储
{
int low;
int high;
double *storage;
};
bool initialize(DoubleArray &arr, int low, int high); //根据low和high为数组分配空间
bool insert(const DoubleArray &arr, int index, double value); //设置数组元素的值
bool fatch(const DoubleArray &arr, int index, double &value); //访问数组元素的值
void cleanup(const DoubleArray &arr); //回收数组空间
#endif
实现文件
#include "DoubleArray.h"
#include
using namespace std;
bool initialize(DoubleArray &arr, int low, int high)
{
arr.low = low;
arr.high = high;
arr.storage = new double[high - low + 1];
if (arr.storage == NULL)
return false;
else return true;
}
void cleanup(const DoubleArray &arr)
{ delete [] arr.storage; }
bool insert(const DoubleArray &arr, int index, double value)
{
if (index < arr.low || index > arr.high)
return false;
arr.storage[index - arr.low] = value;
return true;
}
bool fatch(const DoubleArray &arr, int index, double &value)
{
if (index < arr.low || index > arr.high)
return false;
value = arr.storage[index - arr.low];
return true;
}
应用
#include
using namespace std;
#include "DoubleArray.h"
int main()
{
doubleArray array;
double value;
int low, high, i;
cout << "请输入数组的下标范围:";
cin >> low >> high;
if (!initialize(array, low, high)) {
cout << "空间分配失败";
return 1;
}
for(i=low;i<=high;++i) {
cout << "请输入第" << i << "个元素:";
cin >> value;
insert(array, i, value);
}
while (true) {
cout << "请输入要查找的元素序号(0表示结束):";
cin >> i;
if (i==0) break;
if (fatch(array,i,value))
cout << value << endl;
else cout << "下标越界\n";
}
cleanup(array);
return 0;
}
DoubleArray库的缺点
将函数放入结构体
改进后的头文件
#ifndef _DoubleArray_h
#define _DoubleArray_h
struct DoubleArray
{
int low;
int high;
double *storage;
bool initialize(int lh,int rh);
bool insert(int index,double value);
bool fatch(int index, double &value);
void cleanup();
};
#endif
改进后的DoubleArray函数的实现
bool DoubleArray::initialize(int lh, int rh)
{
low = lh;
high = rh;
storage = new double[high - low + 1];
if (storage == NULL) return false;
else return true;
}
改进后的DoubleArray库的使用
#include
using namespace std;
#include "array.h"
int main()
{
doubleArray array;
double value;
int low, high, i;
cout << "请输入数组的下标范围:";
cin >> low >> high;
if (!array.initialize(low, high)) {
cout << "空间分配失败";
return 1;
}
for(i=low;i<=high;++i) {
cout << "请输入第" << i << "个元素:";
cin >> value;
array.insert(i, value);
}
while (true) {
cout << "请输入要查找的元素序号(0表示结束):";
cin >> i;
if (i==0) break;
if (array.fatch(i,value))
cout << value << endl;
else cout << "下标越界\n";
}
array.cleanup();
return 0;
}
将函数放入结构体的意义
将函数放入结构体是从C到C++的根本改变
类定义的格式
class 类名 {
private:
私有数据成员和成员函数
public:
公有数据成员和成员函数
};
如果某个成员前面没有访问范围说明符,则该成员默认地被认为是私有成员。
DoubleArray类的定义
class DoubleArray
{
private:
int low;
int high;
double *storage;
public:
bool initialize(int lh,int rh);
bool insert(int index,double value);
bool fatch(int index, double &value);
void cleanup();
};
设计一个类SampleCLass
class SampleClass
{
int key;
string value;
public:
void split(SampleClass *,SampleClass *);
}
头文件
#ifndef _rational_h
#define _rational_h
#include
using namespace std;
class Rational {
private:
int num;
int den;
void ReductFraction(); //将有理数化简成最简形式
public:
void create(int n, int d) {num=n; den=d;ReductFraction();}
void add(const Rational &r1, const Rational &r2);
void multi(const Rational &r1, const Rational &r2);
void display() { cout << num << '/' << den; }
};
#endif
有理数类成员函数的实现
#include "Rational.h"
void Rational::add(const Rational &r1, const Rational &r2)
{
num = r1.num * r2.den + r2.num * r1.den;
den = r1.den * r2.den;
ReductFraction();
}
void Rational::multi(const Rational &r1, const Rational &r2)
{
num = r1.num * r2.num;
den = r1.den * r2.den;
ReductFraction();
}
void Rational::ReductFraction()
{
int tmp = (num>den) ? den : num;
for (;tmp > 1;--tmp)
if (num % tmp == 0 && den % tmp == 0) {
num /=tmp;
den /=tmp;
break;
}
}
创建一个类,功能是打印出一句“point”
#include
using namespace std;
class point {
public:
//请补充代码,完成show函数的定义,功能是打印出一句“point”。
void show() {
cout << "point" << endl;
}
};
int main() {
point p1;
point *p;
p = &p1;
p1.show(); //通过对象p1访问show函数
p->show(); //通过指针p访问show函数
return 0;
}
类与对象的关系:类型与变量的关系
怎样定义一个变量,就可以怎样定义一个对象
直接在程序中定义某个类的对象
DoubleArray arr1, arr2, *ap;
static DoubleArray array[10];
申请动态对象
Rational *rp;
rp = new Rational;
rp = new Rational[20];
delete rp;
或delete [] rp;
对象的使用是使用它的成员
公有成员可以被任何函数使用
私有成员只能被自己的成员函数使用
成员的引用
arr1.storage //对象名.数据成员名
rp->num //对象指针->数据成员名
arr1.insert(5, 3.7) //对象名.成员函数名(实际参数表)
rp->add(r1,r2) //对象指针->成员函数名(实际参数表)
有理数类的使用
#include
using namespace std;
#include "Rational.h"
int main() {
int n, d;
Rational r1,r2,r3;
cout << "请输入第一个有理数(分子和分母):";
cin >> n >> d;
r1.create(n,d);
cout << "请输入第二个有理数(分子和分母):";
cin >> n >> d;
r2.create(n,d);
r3.add(r1, r2); //执行r3=r1+r2
r1.display();
cout << "+";
r2.display();
cout << "=";
r3.display();
cout << endl;
r3.multi(r1, r2); //执行r3=r1*r2
r1.display();
cout << "+";
r2.display();
cout << "=";
r3.display();
cout << endl;
return 0;
}
对象赋值
r1.num=r2.num
r1.den=r2.den
每个成员函数都有一个隐藏的指向本类型的指针形参this,指向控制对象
void create(int n, int d)
{
num = n;
den = d;
}
void create(Rational *this, int n, int d)
{
this->num = n;
this->den = d;
}
class SampleClass
{
int a;
public:
SampleClass add()
{
/*
这个函数实现了将变量a增加1的功能
最后返回增加1前的对象(不要求地址相同)
*/
SampleClass temp=*this;
a++;
return temp;
}
}
如何知道哪个是构造函数呢? 构造函数的名字必须与类名相同
DoubleArray类的构造函数
DoubleArray(int lh, int rh)
{
low = lh;
high = rh;
storage = new double[high - low + 1];
}
构造函数的使用
DoubleArray array(20, 30);
Rational类的构造函数
Rational(int n1, int n2)
{
num = n1;
den = n2;
ReducFraction();
}
Rational r(2,7);
动态对象的初始化
p = new DoubleArray(20, 30);
p = new Rational(1, 5);
class DoubleArray{
int low;
int high;
double *storage;
public:
DoubleArray(int lh, int rh):low(lh), high(rh);
DoubleArray(const DoubleArray &);
bool insert(int index, double value);
bool fatch(int index, double &value);
~DoubleArray() {delete [] storage;}
};
DoubleArray类的使用
#include
using namespace std;
#include "DoubleArray.h"
int main()
{
doubleArray array(20,30);
double value;
int i;
for(i=20;i<=30;++i) {
cout << "请输入第" << i << "个元素:";
cin >> value;
array.insert(i, value);
}
while (true) {
cout << "请输入要查找的元素序号(0表示结束):";
cin >> i;
if (i==0) break;
if (array.fatch(i,value))
cout << value << endl;
else cout << "下标越界\n";
}
return 0;
}
operator@
重载成成员函数
class Rational {
private:
int num;
int den;
void ReductFraction();
public:
Rational(int n = 0, int d = 1)
{
num = n;
den = d;
}
Rational operator+(const Rational &r1) const;
Rational operator*(const Rational &r1) const;
bool operator==(const Rational &r1) const;
void display() const {
cout << num << '/' << den;
}
};
Rational Rational::operator+(const Rational &r1) const
{
Rational tmp;
tmp.num = num*r1.den + r1.num*den;
tmp.den = den* r1.den;
tmp.ReductFraction();
return tmp;
}
Rational Rational::operator*(const Rational &r1) const
{
Rational tmp;
tmp.num = num*r1.num;
tmp.den = den*r1.den;
tmp.ReductFraction();
return tmp;
}
bool Rational::operator==(const Rational &r1) const
{
return num == r1.num && den == r1.den;
}
重载成全局函数
class Rational {
friend Rational operator+(const Rational &r1, const Rational &r2);
friend Rational operator*(const Rational &r1, const Rational &r2);
friend bool operator==(const Rational &r1, const Rational &r2);
private:
int num;
int den;
void ReductFraction();
public:
Rational(int n = 0, int d = 1)
{
num = n;
den = d;
}
void display() const {
cout << num << '/' << den;
}
};
Rational operator+(const Rational &r1, const Rational &r2)
{
Rational tmp;
tmp.num = r2.num*r1.den + r1.num*r2.den;
tmp.den = r2.den* r1.den;
tmp.ReductFraction();
return tmp;
}
Rational operator*(const Rational &r1,const Rational &r2)
{
Rational tmp;
tmp.num = r2.num*r1.num;
tmp.den = r2.den*r1.den;
tmp.ReductFraction();
return tmp;
}
bool Rational::operator==(const Rational &r1,const Rational &r2)
{
return r2.num == r1.num && r2.den == r1.den;
}
有理数类的使用
int main()
{
Rational r1(1,6), r2(1,6), r3;
r3 = r1 + r2;
r1.display(); cout << "+"; r2.display();
cout << "="; r3.display(); cout << endl;
r3 = r1 * r2;
r1.display(); cout << "*"; r2.display();
cout << "="; r3.display(); cout << endl;
return 0;
}
随堂测验
//题目描述:
//补全Int类,使得程序的输出为:
//1
//2
//3
//4
//5
#include
using namespace std;
class Int
{
static int addtime;
public:
Int(int x) {}
friend int operator+(const Int &r1, const Int &r2)
{
return ++addtime;
}
};
int Int::addtime = 0;
int main()
{
Int a(1), b(1), c(1);
cout << a + a << endl;
cout << b + b << endl;
cout << b + c << endl;
cout << c + c << endl;
cout << a + a << endl;
}
class Complex{
friend Complex operator+(const Complex &x, const Complex &y);
friend istream& operator>>(istream &is, Complex &obj);
friend ostream& operator<<(ostream &os, const Complex &obj);
private:
Rational real; //实部
Rational imag; //虚部
public:
Complex(int r1 = 0, int r2 = 1, int i1 = 0, int i2 = 1): real(r1,r2),imag(i1,i2){}
Complex(Rational r1, Rational r2): real(r1), imag(r2) {}
};
Complex operator+(const Complex &x, const Complex &y)
{ return Complex(x.real + y.real, x.imag + y.imag);}
istream & operator>>(istream &is, Complex &obj)
{
cout << "请输入实部";
is >> obj.real;
cout << "请输入虚部";
is >> obj.imag;
return is;
}
ostream & operator<<(ostream &os, const Complex &obj)
{
os << '(' << obj.real << "+" << obj.imag << "i" << ')';
return os;
}
int main()
{
Complex x1,x2,x3;
cout << "请输入x1:\n";
cin >> x1;
cout << "请输入x2: \n";
cin >> x2;
x3 = x1 + x2;
cout << x1 << "+" << x2 << "=" << x3 << endl;
return 0;
};
Linklist::Node x;
class 派生类名: 派生方法 基类名
{
//派生类新增的数据成员和成员函数
};
派生实例
class base{
int x;
public:
void setx(int k);
};
class derived1:public base {
int y;
public:
void sety(int k);
};
此时Derived1有x,y两个数据成员和setx,sety两个成员函数。其中x不可访问,y是私有的,setx()和sety()均是公有的。
public继承 | protected继承 | private继承 | |
---|---|---|---|
基类public成员 | public | protected | private |
基类protected成员 | protected | protected | private |
基类private成员 | 不可访问 | 不可访问 | 不可访问 |
注:不可访问指派生类不可访问基类成员,private则指基类成员作为派生类的private成员
通过定义新的类使得在主程序不变的情况下系统功能得到扩展。