码迷,mamicode.com
首页 > 编程语言 > 详细

c++类模板之间友元函数调用

时间:2015-11-23 23:39:56      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:

 1 #include <stdio.h>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 template<typename T> class BTree;
 7 
 8 /***************************节点类模板*********************************/
 9 template<typename T>
10 class BTreeNode{
11     friend void BTree<T>::Print(BTreeNode<T> *t);
12     friend void BTree<T>::PreOrder(BTreeNode<T> *t);
13     friend int BTree<T>::Deepth(BTreeNode<T> *t);
14     friend void BTree<T>::Insert(BTreeNode<T> *t, int n);
15 
16 public:
17     BTreeNode(){ data = NULL; left = right = NULL; }
18     BTreeNode(const T& val){ data = val; left = right = NULL; }
19     BTreeNode(const T& val, BTreeNode<T> *l, BTreeNode<T> *r){ data = val; left = l; right = r; }
20     ~BTreeNode(){ delete left; delete right; }
21 
22 private:
23     T data;
24     BTreeNode<T> *left;
25     BTreeNode<T> *right;
26 };
27 
28 /***************************树类模板**********************************/
29 template<typename T>
30 class BTree{
31 public:
32     void Print(BTreeNode<T> *t);
33     void PreOrder(BTreeNode<T> *t);
34     int Deepth(BTreeNode<T> *t);
35     void Insert(BTreeNode<T> *t,int n);
36 private:
37     BTreeNode<T> *root;
38 };
39 
40 template<typename T>
41 void BTree<T>::Print(BTreeNode<T> *t)
42 {
43     cout << t->data << endl;
44 }
45 
46 
47 template<typename T> 
48 void BTree<T>::PreOrder(BTreeNode<T> *t)
49 {
50     if (t != NULL)
51     {
52         Print(t);
53         PreOrder(t->left);
54         PreOrder(t->right);
55     }
56 }
57 
58 template<typename T> 
59 int BTree<T>::Deepth(BTreeNode<T> *t)
60 {
61     if (t == NULL)
62     {
63         return 0;
64     }
65     int left = 1;
66     int right = 1;
67     left += Deepth(t->left);
68     right += Deepth(t->right);
69     return left >= right ? left : right;
70 }
71 
72 //右边的节点比左边大10
73 template<typename T>
74 void BTree<T>::Insert(BTreeNode<T> *t, int n)
75 {
76     if (n < 0)
77     {
78         return;
79     }
80     int i = ii;
81     t->left = new BTreeNode<T>(ii++);
82     //i = ii;
83     Insert(t->left, n - 1);
84     t->right = new BTreeNode<T>(i + 10);
85     Insert(t->right, n - 1);
86 }

友元函数可以访问封装好的类的私有成员,无疑破坏了类的封装性。不过确实可以提高很多发开的效率。
以前用c语言写链表等,都用结构体来定义一个点。在c++中,用类代替了结构体:确实,类和结构体差不多,只是类可以有私有变量,而结构体都是公有的。
在写二叉树时发现了这样写需要注意的。
代码在上面。main就不写了。
首先要写一个节点类:
/***************************节点类模板*********************************/
template<typename T>
class BTreeNode{
    friend void BTree<T>::Print(BTreeNode<T> *t);
    friend void BTree<T>::PreOrder(BTreeNode<T> *t);
    friend int BTree<T>::Deepth(BTreeNode<T> *t);
    friend void BTree<T>::Insert(BTreeNode<T> *t, int n);

public:
    BTreeNode(){ data = NULL; left = right = NULL; }
    BTreeNode(const T& val){ data = val; left = right = NULL; }
    BTreeNode(const T& val, BTreeNode<T> *l, BTreeNode<T> *r){ data = val; left = l; right = r; }
    ~BTreeNode(){ delete left; delete right; }

private:
    T data;
    BTreeNode<T> *left;
    BTreeNode<T> *right;
};

除了基本的声明,再声明几个友元函数给之后的BTree类调用,BTreeNode只是表示节点,而树是很多节点相连的。所以下面写BTree类,实现树的一些功能。需要注意的是:声明友元的时候,不能跟普通的外部函数一样,声明类或类模板的函数,需要加上域的限制。想想也是,否则编译器怎么能之后你要调用到底是哪个函数呢?因为假如在类内还类外都有同一个名字的函数,那就出事了。所以限定域肯定是有的!!!

/***************************树类模板**********************************/
template<typename T>
class BTree{
public:
    void Print(BTreeNode<T> *t);
    void PreOrder(BTreeNode<T> *t);
    int Deepth(BTreeNode<T> *t);
    void Insert(BTreeNode<T> *t,int n);
private:
    BTreeNode<T> *root;
};

template<typename T>
void BTree<T>::Print(BTreeNode<T> *t)
{
    cout << t->data << endl;
}


template<typename T> 
void BTree<T>::PreOrder(BTreeNode<T> *t)
{
    if (t != NULL)
    {
        Print(t);
        PreOrder(t->left);
        PreOrder(t->right);
    }
}

template<typename T> 
int BTree<T>::Deepth(BTreeNode<T> *t)
{
    if (t == NULL)
    {
        return 0;
    }
    int left = 1;
    int right = 1;
    left += Deepth(t->left);
    right += Deepth(t->right);
    return left >= right ? left : right;
}

//右边的节点比左边大10
template<typename T>
void BTree<T>::Insert(BTreeNode<T> *t, int n)
{
    if (n < 0)
    {
        return;
    }
    int i = ii;
    t->left = new BTreeNode<T>(ii++);
    //i = ii;
    Insert(t->left, n - 1);
    t->right = new BTreeNode<T>(i + 10);
    Insert(t->right, n - 1);
}

可以看到,在类模板里还是跟正常一样声明函数,和在类外定义函数。但是当你在主函数使用这些定义的函数就会出错。那是因为在定义友元的时候没有声明类模板。

在第一个类模板就是BTreeNode之前就上很重要的一句:

template<typename T> class BTree;

就完美了。另外记住:以后在使用之前先声明,否则无论是使用和定义都会出现问题。

我写程序一直都是class什么,class什么,int main()什么。其实先写定义头是个好习惯!!!

 

c++类模板之间友元函数调用

标签:

原文地址:http://www.cnblogs.com/wyc199288/p/4989851.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!