友元概念就不罗嗦了,使用也简单,就两种形式:
1.友元函数:friend ret-type classname::funname(....);
2.友元类:friend class classname;
唯一要注意的就是不管是友元函数还是友元类,定义友元关系前必须先声明
友元类其实还是有些故事要说的,一旦类继承起来友元关系还是有些小复杂的,下面简单说明:
C中声明A是其友元类,那么最基本的就是A可以使用C中的private方法或者对象。
图中可见,A是B的基类,C是D的基类。ABCD中就有如下关系:
1.B新增的方法不能访问C的私有成员
2.B从A继承而来的方法可以访问C的私有成员
3.A只能访问D中从C中继承而来的私有成员,D中新增的私有成员不能访问!
总结起来:
(1)友元关系不可以继承,但对已有的方法来说访问权限不改变。
(2)如果改写基类的方法则访问权限改变
(3)友元关系不具有传递性
若类B是类A的友元,类C是B的友元,类C不一定是类A的友元
下面一个例子说明了友元模板类的定义。
#include <iostream>
using namespace std;
//using std::cout;
template <typename T>
class Node
{
template <typename T> friend class ListNode;
//友元模板类的声明,这种写法friend class ListNode<T>;有的教材提到,没编译通过
private:
T data;
Node<T> *next; //模板函数变量的定义一定不要玩了参数列表
};
template <typename T>
class ListNode
{
private:
Node<T> *first;
public:
ListNode(){ first = 0; }
~ListNode();
ListNode & Insert(int k,T &x);
ListNode & Delete(T &x);
bool IsEmpty()const;
int Length()const;
void display()const;
};
template <typename T>
ListNode<T>::~ListNode()
{
Node<T> *curr = first->next;
Node<T> *prev = first;
while(curr)
{
delete prev;
prev = curr;
curr = curr->next;
}
}
template<typename T>
bool ListNode<T>::IsEmpty()const
{
return first == 0
}
template <typename T>
ListNode<T> & ListNode<T>::Insert(int k,T &x)
{
Node<T> *curr = first;
Node<T> *temp;
int index =0;
temp = first;
temp = new Node<T>;
temp->data = x;
temp->next =0;
if(k<0 || k>Length())
{
cout<<"the input location is illegal"<<endl;
return *this;
//exit(1);
}
if(k==0 && first==0)
{
temp->next = first;
first = temp;
}
else
{
for(index=0;index<k;index++)
curr = curr->next;
temp->next = curr->next;
curr->next = temp;
}
return *this;
}
template <typename T>
int ListNode<T>::Length()const
{
int index = 0;
Node<T> *curr = first;
while(curr)
{
index++;
curr = curr->next;
}
return index;
}
template <typename T>
ListNode<T> & ListNode<T>::Delete(T &x)
{
Node<T> *curr = first->next;
Node<T> *prev = first;
while(curr)
{
if(first->data == x)
{
first = first->next;
delete prev;
}
else
{
if(curr->data == x)
{
prev->next = curr->next;
delete curr;
}
}
prev = curr;
curr = curr->next;
}
return *this;
}
template <typename T>
void ListNode<T>::display()const
{
Node<T> *curr = first;
while(curr)
{
cout<<curr->data<<" ";
curr = curr->next;
}
}