c++友元类,友元函数

时间:2021-08-14 19:06:24
#ifndef _BST_H_HITHUMING_INCLUDE_
#define _BST_H_HITHUMING_INCLUDE_
#include<iostream>
using namespace std;
template<class T>
class node
{
public:
    node():lchild(NULL),rchild(NULL) {};
    node(T p)
    {
        this->data=p;
        lchild=NULL;
        rchild=NULL;
    };
    ~node()
    {
        delete this;
    };
    void setup(T d,node<T>* l,node<T> r)
    {
        data=d;
        lchild=l;
        rchild=r;
    };
    T return_data()
    {
        return data;
    };
    node<T>* return_lc()
    {
        return lchild?lchild:NULL;
    };
    node<T>* return_rc()
    {
        return rchild?rchild:NULL;
    };
    friend class BST;//声明啦友元类,为什么下面还不能访问?
private:
    T data;
    node<T>* lchild,rchild;
};
template <class T>
class  BST
{
public:
    void CreateBST();//返回父节点的指针
    void InsertBST(T key,node<T>* F);//插入的类型,还有插入的位置
    node<T>* SearchBST(T key,node<T>* F);//查找
    void in_order(node<T>* t);
    node<T>* return_rt();
private:
    node<T>* root;
};
template <class T>
void BST<T>::CreateBST()
{
    root=NULL;
    T m;
    while(cin >> m&&m!='#')
        InsertBST(m,root);
}
template <class T>
void BST<T>::InsertBST(T key,node<T>* F)
{
    if(F==NULL)
    {
//        F=new node<T>;
        F.setup(key,NULL,NULL);
    }
    else if (key<F.return_data())
        InsertBST(key,F.return_lc());
    else if (key > F.return_data())
        InsertBST(key,F.return_rc());
    else return;
}
template <class T>
node<T>* BST<T>::SearchBST(T k,node<T>* F)
{
    node<T>* p =F;
    if (p== NULL || k == p.return_data() ) /* 递归终止条件*/
        return p;
    if ( k < p.return_data())
        return (SearchBST (k, p.return_lc())); /* 查找左子树*/
    else
        return (SearchBST(k,p.return_rc())) ; /* 查找右子树*/
}
template <class T>
void BST<T>::in_order(node<T>* t)
{
    if(t!=NULL)
    {
        in_order(t.return_lc());
        cout << t.return_data();
        in_order(t.return_rc());
    }
}
#endif

上面一个查找树的程序,可能实现上还有问题,但是为什么生命友元类啦还是不能访问?求解释!

8 个解决方案

#1



//file:main.cpp
#include  "BST.h"
int main()
{
  BST<int> test;
  test.CreateBST();
  test.in_order(test.return_rt());
 return 0;
}

#2


把声明的友元类定义放在class node类之前看看 c++友元类,友元函数

#3



class BST;//声明啦友元类,为什么下面还不能访问
template<class T>
class node
{
public:
    friend class BST;
    node():lchild(NULL),rchild(NULL) {};
    node(T p)
    {
        this->data=p;
        lchild=NULL;
        rchild=NULL;
    };
    ~node()
    {
        delete this;
    };
    void setup(T d,node<T>* l,node<T> r)
    {
        data=d;
        lchild=l;
        rchild=r;
    };
    T return_data()
    {
        return data;
    };
    node<T>* return_lc()
    {
        return lchild?lchild:NULL;
    };
    node<T>* return_rc()
    {
        return rchild?rchild:NULL;
    };
private:
    T data;
    node<T>* lchild,rchild;
};
是这样吗?还是不对,只不过错误少啦!

#4


引用 2 楼 xuebichongkafei 的回复:
把声明的友元类定义放在class node类之前看看
是楼上那样吗?

#5


template<typename U> friend class BST;

#6


引用 楼主 creazierHIT 的回复:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929……

做了修改,编译可以通过,具体实现逻辑我没细看 c++友元类,友元函数

#include <iostream>
#include <cstring>
using namespace std;

// 添加BST模板的前置声明,否则node中无法声明BST<T>为友元类
template <class T>
class BST;

template<class T>
class node
{
public:
    node():lchild(NULL),rchild(NULL) {};
    node(T p)
    {
        this->data=p;
        lchild=NULL;
        rchild=NULL;
    };
    ~node()
    {
        delete this;
    };

    // 代码这里错了,第三个参数应该是指针类型的
    // void setup(T d,node<T>* l,node<T> r)
    void setup(T d,node<T>* l,node<T>* r)
    {
        data=d;
        lchild=l;
        rchild=r;
    };

    T return_data()
    {
        return data;
    };

    // 这里不需要判断,因为lchild和rchild都有合理默认值的
    node<T>* return_lc() { return lchild; };
    node<T>* return_rc() { return rchild; };

//    friend class BST;//声明啦友元类,为什么下面还不能访问?
    // 那是因为仅仅写BST还不够
    friend class BST<T>;
private:
    T data;
    // 这里又错了,这样写rchild不是指针,而是node<T>类型
    // node<T>* lchild,rchild;
    node<T> *lchild, *rchild;
};

template <class T>
class BST
{
public:
    void CreateBST();//返回父节点的指针
    void InsertBST(T key,node<T>* F);//插入的类型,还有插入的位置
    node<T>* SearchBST(T key,node<T>* F);//查找
    void in_order(node<T>* t);
    node<T>* return_rt() { return root; }
private:
    node<T>* root;
};

template <class T>
void BST<T>::CreateBST()
{
    root=NULL;
    T m;
    while(cin >> m&&m!='#')
        InsertBST(m,root);
}

template <class T>
void BST<T>::InsertBST(T key,node<T>* F)
{
// 这里F是指针,怎么能.呢?
    if(F==NULL)
    {
     // F为空怎么还调用?我反正只改语法,能编译就好,细节你再慢慢修改哦
        F->setup(key,NULL,NULL);
    }
    else if (key < F->return_data())
        InsertBST(key,F->return_lc());
    else if (key > F->return_data())
        InsertBST(key,F->return_rc());
    else return;
}

template <class T>
node<T>* BST<T>::SearchBST(T k,node<T>* F)
{
    node<T>* p =F;
    // 这里p也是指针,同样要用->操作符
    if (p== NULL || k == p->return_data() ) /* 递归终止条件*/
        return p;
    if ( k < p->return_data())
        return (SearchBST (k, p->return_lc())); /* 查找左子树*/
    else
        return (SearchBST(k,p->return_rc())) ; /* 查找右子树*/
}

template <class T>
void BST<T>::in_order(node<T>* t)
{
    if(t!=NULL)
    {
     // 同上
        in_order(t->return_lc());
        cout << t->return_data();
        in_order(t->return_rc());
    }
}

int main(int argc, char **argv)
{
BST<int> b;
b.CreateBST();
b.InsertBST(3, new node<int>());
b.SearchBST(3, new node<int>());
b.in_order(new node<int>());
b.return_rt();
return 0;
}

#7


引用 5 楼 openXMPP 的回复:
template<typename U> friend class BST;

这样写算是在类型检查上开了个口子,BST<int>也可以访问node<double>的private成员了。

#8


引用 7 楼 tofu_ 的回复:
引用 5 楼 openXMPP 的回复:template<typename U> friend class BST;
这样写算是在类型检查上开了个口子,BST<int>也可以访问node<double>的private成员了。
谢谢!!!!!!

#1



//file:main.cpp
#include  "BST.h"
int main()
{
  BST<int> test;
  test.CreateBST();
  test.in_order(test.return_rt());
 return 0;
}

#2


把声明的友元类定义放在class node类之前看看 c++友元类,友元函数

#3



class BST;//声明啦友元类,为什么下面还不能访问
template<class T>
class node
{
public:
    friend class BST;
    node():lchild(NULL),rchild(NULL) {};
    node(T p)
    {
        this->data=p;
        lchild=NULL;
        rchild=NULL;
    };
    ~node()
    {
        delete this;
    };
    void setup(T d,node<T>* l,node<T> r)
    {
        data=d;
        lchild=l;
        rchild=r;
    };
    T return_data()
    {
        return data;
    };
    node<T>* return_lc()
    {
        return lchild?lchild:NULL;
    };
    node<T>* return_rc()
    {
        return rchild?rchild:NULL;
    };
private:
    T data;
    node<T>* lchild,rchild;
};
是这样吗?还是不对,只不过错误少啦!

#4


引用 2 楼 xuebichongkafei 的回复:
把声明的友元类定义放在class node类之前看看
是楼上那样吗?

#5


template<typename U> friend class BST;

#6


引用 楼主 creazierHIT 的回复:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929……

做了修改,编译可以通过,具体实现逻辑我没细看 c++友元类,友元函数

#include <iostream>
#include <cstring>
using namespace std;

// 添加BST模板的前置声明,否则node中无法声明BST<T>为友元类
template <class T>
class BST;

template<class T>
class node
{
public:
    node():lchild(NULL),rchild(NULL) {};
    node(T p)
    {
        this->data=p;
        lchild=NULL;
        rchild=NULL;
    };
    ~node()
    {
        delete this;
    };

    // 代码这里错了,第三个参数应该是指针类型的
    // void setup(T d,node<T>* l,node<T> r)
    void setup(T d,node<T>* l,node<T>* r)
    {
        data=d;
        lchild=l;
        rchild=r;
    };

    T return_data()
    {
        return data;
    };

    // 这里不需要判断,因为lchild和rchild都有合理默认值的
    node<T>* return_lc() { return lchild; };
    node<T>* return_rc() { return rchild; };

//    friend class BST;//声明啦友元类,为什么下面还不能访问?
    // 那是因为仅仅写BST还不够
    friend class BST<T>;
private:
    T data;
    // 这里又错了,这样写rchild不是指针,而是node<T>类型
    // node<T>* lchild,rchild;
    node<T> *lchild, *rchild;
};

template <class T>
class BST
{
public:
    void CreateBST();//返回父节点的指针
    void InsertBST(T key,node<T>* F);//插入的类型,还有插入的位置
    node<T>* SearchBST(T key,node<T>* F);//查找
    void in_order(node<T>* t);
    node<T>* return_rt() { return root; }
private:
    node<T>* root;
};

template <class T>
void BST<T>::CreateBST()
{
    root=NULL;
    T m;
    while(cin >> m&&m!='#')
        InsertBST(m,root);
}

template <class T>
void BST<T>::InsertBST(T key,node<T>* F)
{
// 这里F是指针,怎么能.呢?
    if(F==NULL)
    {
     // F为空怎么还调用?我反正只改语法,能编译就好,细节你再慢慢修改哦
        F->setup(key,NULL,NULL);
    }
    else if (key < F->return_data())
        InsertBST(key,F->return_lc());
    else if (key > F->return_data())
        InsertBST(key,F->return_rc());
    else return;
}

template <class T>
node<T>* BST<T>::SearchBST(T k,node<T>* F)
{
    node<T>* p =F;
    // 这里p也是指针,同样要用->操作符
    if (p== NULL || k == p->return_data() ) /* 递归终止条件*/
        return p;
    if ( k < p->return_data())
        return (SearchBST (k, p->return_lc())); /* 查找左子树*/
    else
        return (SearchBST(k,p->return_rc())) ; /* 查找右子树*/
}

template <class T>
void BST<T>::in_order(node<T>* t)
{
    if(t!=NULL)
    {
     // 同上
        in_order(t->return_lc());
        cout << t->return_data();
        in_order(t->return_rc());
    }
}

int main(int argc, char **argv)
{
BST<int> b;
b.CreateBST();
b.InsertBST(3, new node<int>());
b.SearchBST(3, new node<int>());
b.in_order(new node<int>());
b.return_rt();
return 0;
}

#7


引用 5 楼 openXMPP 的回复:
template<typename U> friend class BST;

这样写算是在类型检查上开了个口子,BST<int>也可以访问node<double>的private成员了。

#8


引用 7 楼 tofu_ 的回复:
引用 5 楼 openXMPP 的回复:template<typename U> friend class BST;
这样写算是在类型检查上开了个口子,BST<int>也可以访问node<double>的private成员了。
谢谢!!!!!!