发现问题
在完成老师布置的作业时遇见的一个现象,觉得很奇怪,故加以研究。描述如下:
编写一个模板类DLinkList实现双链表结构,定义如下:
//定义数据元素的结构
template<class T>
struct Node {
T data;
Node<T>* prior;
Node<T>* next;
};
//定义双链表类
template<class T>
class DLinkList {
private:
Node<T>* front;
public:
//无参构造函数
DLinkList();
//有参构造函数。data[],数据数组;n,数组长度
DLinkList(T data[], int n);
//析构函数
~DLinkList();
//插入数据元素。i,插入位置;x,插入数据
void Insert(int i, T x);
//删除数据元素。i,删除位置;返回数据
T Delete(int i);
//按位查找数据元素。i,查找位置;返回指针
Node<T>* Get(int i);
//按值查找数据元素。x,查找值;返回第一次出现的位置
int Locate(T x);
//获取链表长度。返回长度
int GetLength();
//打印链表中所有数据元素
void PrintList();
//合并两条链表。a,b,要合并的链表引用;返回链表引用
DLinkList<T>& Combine(DLinkList<T>& a, DLinkList<T>& b);
//获取头指针。返回头指针
Node<T>* GetFront();
};
在实现其中的成员函数DLinkList<T>& Combine(DLinkList<T>& a, DLinkList<T>& b);
时,发现了这样的一个现象:函数的参数明明是类对象,却可以直接通过对象名.私有成员
访问该对象的私有成员。DLinkList<T>& Combine(DLinkList<T>& a, DLinkList<T>& b);
的实现如下:
//合并两条链表
template<class T>
DLinkList<T>& DLinkList<T>::Combine(DLinkList<T>& a, DLinkList<T>& b) {
int length = a.GetLength() + b.GetLength(); //两个链表中所有数据元素的个数
T* data = new T[length]; //申请动态内存来存放数据
//将两个链表中的数据元素存放到data数组中
Node<T>* p = a.front->next;
int i = 0;
while (p) {
data[i] = p->data;
p = p->next;
i++;
}
p = b.front->next;
while (p) {
data[i] = p->data;
p = p->next;
i++;
}
//将data数组从小到大排序
for (i = 0; i < length; i++) {
for (int j = i; j < length; j++) {
if (data[i] > data[j]) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
static DLinkList<T>c(data, length); //构建静态DLinkList对象c,存放合并后的所有数据到链表中
delete[]data; //释放动态内存,防止内存泄漏
data = NULL; //指针置空,防止指针悬挂
p = c.front->next;
//删除链表中的重复元素
while (p) {
while (p->next != NULL && p->data == p->next->data) {
Node<T>* q = p->next;
p->next = q->next;
q->next->prior = p;
delete q;
}
p = p->next;
}
return c; //返回静态DLinkList对象c
}
其中直接通过a.front->next
来访问对象a中的私有成员front
。
解释
因为函数DLinkList<T>& Combine(DLinkList<T>& a, DLinkList<T>& b)
是DLinkList
类的成员函数,函数处于类的内部,因此对于相同类的对象,是可以通过对象名.私有成员
来调用的。若是在类的外部,如在main()
中使用对象名.私有成员
是一定会报错的。