c++类模板之间友元函数调用
2015-11-23 22:05
260 查看
#include <stdio.h> #include <iostream> using namespace std; template<typename T> class BTree; /***************************节点类模板*********************************/ 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; }; /***************************树类模板**********************************/ 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); } 友元函数可以访问封装好的类的私有成员,无疑破坏了类的封装性。不过确实可以提高很多发开的效率。 以前用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++ primer》英文第五版阅读笔记(十六)——赋值运算符
- 【UVALive】3029.City Game<C++>
- 三色排序问题/(荷兰国旗问题)(C++版)
- C++ 表达式
- 【应用笔记】【AN003】VC++环境下基于以太网的4-20mA电流采集
- 二叉树的基本操作的c++实现
- C++ for_each学习笔记
- C/C++中void用法总结
- 数据抽象与封装的好处--【primer第四版】
- C/C++学习(二)输入n个整数,输出其中最小的k个。
- 合并两个有序数组(C++版)
- c++之判断栈的弹出是否合法
- c++之栈的顺序表实现
- C语言初学者画图练习
- C语言初学者简单语法综合练习
- C语言初学者简单语法小测
- c++栈之带括号的四则运算
- c++友元类及友元函数
- Python中的for与其他类C语言的比较(如c++,c#)
- 1、让自己习惯c++