1. 任务描述
使用List
类的构造函数,实现其2个子类的构造函数。 List
类已提供2个构造函数,其一是拷贝构造函数,另一个以1
个int
作为参数,其作用是初始化size
的值;同时int
形参的默认值是0。 ArrayList
类和LinkedList
类均提供4
个构造函数,请参考实训作业10和实训作业11。
2. 相关知识
考虑如下类:
class List{
protected:
int size;
};
class ArrayList : public List{
public:
ArrayList():size(0){}
};
你希望初始化一个空的ArrayList
对象,因此size
初始化为0
。很遗憾,这是错误的,因为C++不允许这么做。因为构造函数初始化列表只能列出本类的成员,而size
是从父类继承而来的,不是本类的成员。这个解释稍微有点拗口,但无论如何,C++不准这么做。 这样做就是合法的,因为size
是protected
:
ArrayList::ArrayList(){size=0;}
同样很遗憾,这样做又不是初始化(请参考实训2)。而且,如果size
是私有的,这样做也是行不通的。如何使用初始化列表初始化从父类继承而来的成员呢?答案是在初始化列表中调用父类的构造函数。当然这要求父类首先提供相应的构造函数。
class List{
protected:
int size;
public:
List(int s=0):size(s){}
};
class ArrayList : public List{
public:
ArrayList():List(){}
//在子类的初始化列表中调用父类的构造函数
};
以上就能成功的将ArrayList
对象中的size
初始化为0
。这种情况下,即使size
是private
,ArrayList
类的构造函数仍然可以顺利执行。
3. 编程要求
本关一共有6个文件,List.h、ArrayList.h、LinkedList.h和main.cpp内容已写好,用户不允许改变。用户需要编写ArrayList.cpp和LinkedList.cpp中的内容,使得程序能够正确运行。 具体说来,需要提供头文件中指定的构造函数以及析构函数。
List.h内容如下:
#ifndef _LIST_H_
#define _LIST_H_
class List{
protected:
int size;
public:
//兼具默认构造函数和功能构造函数
List(int s=0):size(s){}
//拷贝构造函数
List(const List&rhs):size(rhs.size){}
//取函数,从此以后不再提供存函数
int getSize()const{return size;}
};
#endif // _LIST_H_
ArrayList.h内容如下:
#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
#include "List.h"
class ArrayList : public List{
private:
int *data; //真正保存数据的地方
int capacity;//容量
public:
//默认构造函数,构造一个逻辑为空的顺序表
ArrayList();
//拷贝构造函数,构造一个逻辑上与参数内容相同的顺序表
ArrayList(const ArrayList&rhs);
//原生数组构造函数,构造一个内容与给定数组相同的顺序表
ArrayList(int const a[],int n);
//填充构造函数,构造一个内容为n个value的顺序表
ArrayList(int n,int value);
//析构函数,一定要自行实现,否则有内存泄漏
~ArrayList();
};
#endif // _ARRAYLIST_H_
LinkedList.h内容如下:
#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_
#include "List.h"
class LinkedList : public List{
public:
//这是单链表节点的结构体
struct Node{
int data;
Node *next;
Node(int a=0,Node *b=nullptr):data(a),next(b){}
};
private:
Node *head;//链表的头结点
public:
//默认构造函数,构造一个逻辑为空的链表
LinkedList();
//拷贝构造函数,构造一个逻辑上与参数内容相同的链表
LinkedList(const LinkedList&rhs);
//原生数组构造函数,构造一个内容与给定数组相同的链表
LinkedList(int const a[],int n);
//填充构造函数,构造一个内容为n个value的链表
LinkedList(int n,int value);
//析构函数,一定要自行实现,否则有内存泄漏
~LinkedList();
};
#endif // _LINKEDLIST_H_
main.cpp内容如下:
#include <iostream>
#include "List.h"
#include "ArrayList.h"
#include "LinkedList.h"
using namespace std;
int const A[] = {100,200,300};
int main()
{
List a;
ArrayList b(A,3),c(4,9);
ArrayList d(c);
LinkedList e(A,3),f(4,9);
LinkedList g(f);
cout<<a.getSize()
<<b.getSize()<<c.getSize()<<d.getSize()
<<e.getSize()<<f.getSize()<<g.getSize()
<<endl;
return 0;
}
答案如下:
ArrayList.cpp内容如下:
#include "ArrayList.h"
// 默认构造函数,构造一个逻辑为空的顺序表
ArrayList::ArrayList() : capacity(0), data(nullptr) {}
// 拷贝构造函数,构造一个逻辑上与参数内容相同的顺序表
ArrayList::ArrayList(const ArrayList& rhs) : List(rhs), capacity(rhs.capacity) {
data = new int[capacity];
for (int i = 0; i < size; i++) {
data[i] = rhs.data[i];
}
}
// 原生数组构造函数,构造一个内容与给定数组相同的顺序表
ArrayList::ArrayList(int const a[], int n) : List(n), capacity(n) {
data = new int[capacity];
for (int i = 0; i < size; i++) {
data[i] = a[i];
}
}
// 填充构造函数,构造一个内容为n个value的顺序表
ArrayList::ArrayList(int n, int value) : List(n), capacity(n) {
data = new int[capacity];
for (int i = 0; i < size; i++) {
data[i] = value;
}
}
// 析构函数,一定要自行实现,否则有内存泄漏
ArrayList::~ArrayList() {
delete[] data;
}
LinkedList.cpp内容如下:
#include "LinkedList.h"
// 默认构造函数,构造一个逻辑为空的链表
LinkedList::LinkedList() : head(nullptr) {}
// 拷贝构造函数,构造一个逻辑上与参数内容相同的链表
LinkedList::LinkedList(const LinkedList& rhs) : List(rhs) {
if (rhs.head == nullptr) {
head = nullptr;
} else {
head = new Node(rhs.head->data);
Node* curr = head;
Node* rhsCurr = rhs.head->next;
while (rhsCurr != nullptr) {
curr->next = new Node(rhsCurr->data);
curr = curr->next;
rhsCurr = rhsCurr->next;
}
}
}
// 原生数组构造函数,构造一个内容与给定数组相同的链表
LinkedList::LinkedList(int const a[], int n) : List(n) {
if (n == 0) {
head = nullptr;
} else {
head = new Node(a[0]);
Node* curr = head;
for (int i = 1; i < n; i++) {
curr->next = new Node(a[i]);
curr = curr->next;
}
}
}
// 填充构造函数,构造一个内容为n个value的链表
LinkedList::LinkedList(int n, int value) : List(n) {
if (n == 0) {
head = nullptr;
} else {
head = new Node(value);
Node* curr = head;
for (int i = 1; i < n; i++) {
curr->next = new Node(value);
curr = curr->next;
}
}
}
// 析构函数,一定要自行实现,否则有内存泄漏
LinkedList::~LinkedList() {
Node* curr = head;
while (curr != nullptr) {
Node* temp = curr;
curr = curr->next;
delete temp;
}
}