实验目的:
掌握不同方式下,构造函数和析构函数的执行顺序与构造规则
//原程序 #include#include using namespace std; class MyArray { public: MyArray(int length); ~MyArray(); void Input(); void Display(string); protected: int* alist; int length; }; MyArray::MyArray(int leng) { if (leng <= 0) { cout << "error length"; exit(1); } alist = new int[length]; length = leng; if (alist == NULL) { cout << "assign failure"; exit(1); } cout << "MyArray类对象已创建!" << endl; } MyArray::~MyArray() { delete[] alist; cout << "MyArray类对象已撤销!" << endl; } void MyArray::Display(string str) { int i; int* p = alist; cout << str << length << "个整数:"; for (i = 0; i < length; i++, p++) { cout << *p << ""; } cout << endl; } void MyArray::Input() { cout << "请从键盘输入" << length << "个整数:"; int i; int* p = alist; for (i = 0; i < length; i++, p++) { cin >> *p; } } int main() { MyArray a(5); a.Input(); a.Display("显示排序以前已经输入的"); return 0; }
运行过后,显示结果如上;
析构函数不能正常运行,原因是 构造函数在调用时,leng和length的调用位置不对,应该放在开头。
实验内容:
写出程序运行结果。
声明一个SortArray继承类MyArray,在该类中定义一个函数,具有将输入的整数从小到大进行排序的功能。
#include#include using namespace std; class MyArray { public: MyArray(int length); ~MyArray(); void Input(); void Display(string); protected: int* alist; int length; }; MyArray::MyArray(int leng) { length = leng; if (leng <= 0) { cout << "error length"; exit(1); } alist = new int[length]; if (alist == NULL) { cout << "assign failure"; exit(1); } cout << "MyArray类对象已创建!" << endl; } MyArray::~MyArray() { delete[] alist; cout << "MyArray类对象已撤销!" << endl; } void MyArray::Display(string str) { int i; int* p = alist; cout << str << length << "个整数:"; for (i = 0; i < length; i++, p++) { cout << *p << " "; } cout << endl; } void MyArray::Input() { cout << "请从键盘输入" << length << "个整数:"; int i; int* p = alist; for (i = 0; i < length; i++, p++) { cin >> *p; } } class SortArray :public MyArray { public: SortArray(int length):MyArray(length) { cout << "SortArray类对象已构造" << endl; }; ~SortArray(){ cout << "SortArray类对象已撤销" << endl; }; void paixu(int left, int right); protected: }; void SortArray::paixu(int left, int right) {//快速排序 int i, j, t, temp; int* p = alist; if (left > right) return; temp = p[left]; i = left; j = right; while (i != j) { while (p[j] >= temp && j > i) j--; while (p[i] <= temp && j > i) i++; if (i < j) { t = p[i]; p[i] = p[j]; p[j] = t; } } p[left] = p[i]; p[i] = temp; paixu(left, i - 1); paixu(i + 1, right); } int main() { int n; cout << "排几个数:"; cin >> n; SortArray a(n); a.Input(); a.Display("显示排序以前已经输入的"); a.paixu(0, n -1); a.Display("显示排序以后已经输入的"); return 0; }
实验结果如下图所示:
派生类的声明方法:
声明一个派生类的一般格式为:
class <派生类名>:[继承方式]<基类名>{
[派生类新成员的定义];
}
派生类构造函数的定义方法
派生类构造函数的一般格式为:
派生类名(参数总表):基类名(参数表) {
派生类新增数据成员的初始化语句;
}
含有子对象的派生类的构造函数:
派生类名(参数总表):基类名(参数表0),子对象名1(参数表1),...,子对象名n(参数表n) {
派生类新增成员的初始化语句;
}
在定义派生类对象时,构造函数的调用顺序如下:
调用基类的构造函数,对基类数据成员初始化。
调用子对象的构造函数,对子对象的数据成员初始化。
调用派生类的构造函数体,对派生类的数据成员初始化
- 当基类构造函数不带参数时,派生类不一定需要定义构造函数;然而当基类的构造函数哪怕只带有一个参数,它所有的派生类都必须定义构造函数,甚至所定义的派生类构造函数的函数体可能为空,它仅仅起参数的传递作用。
- 若基类使用默认构造函数或不带参数的构造函数,则在派生类中定义构造函数时可略去“:基类构造函数名(参数表)”,此时若派生类也不需要构造函数,则可不定义构造函数。
- 如果派生类的基类也是一个派生类,每个派生类只需负责其直接基类数据成员的初始化,依次上溯。
排序函数部分:
void SortArray::paixu(int left, int right) {//快速排序
int i, j, t, temp;
int* p = alist;
if (left > right)
return;
temp = p[left];//temp中存的就是基准数
i = left;
j = right;
while (i != j) {
while (p[j] >= temp && j > i) //顺序很重要,要先从右边开始找
j--;
while (p[i] <= temp && j > i)//再找右边的
i++;
//交换两个数在数组中的位置
if (i < j) {
t = p[i];
p[i] = p[j];
p[j] = t;
}
}
//最终将基准数归位
p[left] = p[i];
p[i] = temp;
paixu(left, i - 1);//继续处理左边的,这里是一个递归的过程
paixu(i + 1, right);//继续处理右边的 ,这里是一个递归的过程
}
快速排序的核心是:每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了,速度也快多了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)