模板与友元类的问题

suhuobing 2006-01-17 12:29:17
有四个类:数据类DD,节点类Node,链表类Chain,链表子类ChainChild

文件DD.h
#ifndef DD_H
#define DD_H

template <class T>
class DD
{
public:
DD(){}
~DD(){};
private:
T st;
};

#endif

文件Node.h
template <class T>
class ChainChild;

template <class T>
class Node
{
friend class ChainChild<T>;
public:
Node(){}
~Node(){}
private:
T data;
};

#endif

文件Chain.h
#ifndef Chain_H
#define Chain_H

#include "Node.h"
#include "DD.h"

template <class T>
class ChainChild;

template <class T>
class Chain
{
friend class ChainChild<T>;
public:
Chain(){}
~Chain(){}
private:
Node<T> c;
};

#endif

文件ChainChild.h
#include "DD.h"

template <class T>
class ChainChild : public Chain< DD<T> > //这里DD<T>改成T就不会有问题
{
public:
ChainChild(){}
~ChainChild(){}
void UseP()
{
c; //这里用到了Chain类和Node类的私有成员
c.data;
}
};

文件main.c
#include "Chain.h"
#include "ChainChild.h"

void main()
{
Chain<int> p;
ChainChild<int> la;
la.UseP();
ChainChild<float> lb;
lb.UseP();
LinkW<float> l2;
l2.UseP();
}

编译时提示ChainChild类不能存取Node类和Chain类的私有成员,该如何改正?
...全文
337 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
suhuobing 2006-01-24
  • 打赏
  • 举报
回复
你的当然可以运行,因为你的代码是
class ChainChild : public Node<T>

我的是class ChainChild : public Chain< DD<T> >
说来说去,就是这个public Chain< DD<T> >会引起混乱
suhuobing 2006-01-19
  • 打赏
  • 举报
回复
to zeusnchen() :
首先很感谢你的指教
现在我的目的很简单,就是要ChainChild类可以使用Chain类的私有成员,并且ChainChild类
继承Chain类时一定要public Chain< DD<T>>,Node类的私有成员就先不使用了
我现在的疑惑是为什么你上面所说的是要把Chain类作为ChainChild类的friend类?
我的理解是我的Chain类要做如下改动:

#ifndef Chain_H
#define Chain_H

#include "Node.h"
#include "DD.h"

template <class T>
class ChainChild;

template <class T>
class Chain
{
template <class T2> friend class ChainChild;//这里做了变动,另定义模板
public:
Chain(){}
~Chain(){}
private:
Node<T> c;
};

#endif

但是编译时并不能通过
可否告诉我,具体到我的程序如何解决?
piaochen_2002 2006-01-19
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;


template <class T>
class ChainChild;
template <class T>
class Chain;
template <class T>
class Node
{
friend class ChainChild<T>;
public:
Node(){}
~Node(){}
private:
T data;
};






template <class T>
class ChainChild;

template <class T>
class Chain
{

public:
friend class ChainChild<T> ;
Chain(){
a=10;
}
~Chain(){}
private:
int a;
};


template <class T>
class ChainChild : public Node<T>
{
public:
ChainChild(){}
~ChainChild(){}
void UseP(Chain<T> &temp)
{


cout<<temp.a<<endl;
}
};


void main()
{
Chain<int> p;

ChainChild<int> la;
la.UseP(p);

}
另外我不知道你说的VC不支持是什么意思,我这样写是可以运行的!
piaochen_2002 2006-01-19
  • 打赏
  • 举报
回复
派生类可以访问基类的protected 成员的,你用protected就可以了
zeusnchen 2006-01-19
  • 打赏
  • 举报
回复

你不是要再子类访问父类的private成员么?
所以你才需要把子类申明为父类的friend啊
难道偶弄错了说,呵呵

试了试,貌似MSVC7确实不支持哈
//comfort
suhuobing 2006-01-19
  • 打赏
  • 举报
回复
to zeusnchen() :
我用的确实是vc,看来这个问题很难解决了

你的话我还是不明白
××你不把Chain申明为friend怎么能访问它的private成员呢?
你的这个它是否指派生类ChainChild?问题是ChainChild没有任何私有成员啊
为什么要把父类即Chain类声明为派生类即ChainChild类的友元类?
zeusnchen 2006-01-19
  • 打赏
  • 举报
回复
抱什么错啊
你改动的行有没有错?如果有的话,应该是VC的错哈,我在G++上是没有问题的

》我现在的疑惑是为什么你上面所说的是要把Chain类作为ChainChild类的friend类?
你不把Chain申明为friend怎么能访问它的private成员呢?所以申明为friend是必要的
只是你以前的申明实际上只是把Chain的某个具体化的类申明为friend,这样如果用其它
参数实例化Chain的话就无法访问了。
zeusnchen 2006-01-18
  • 打赏
  • 举报
回复
继承类是不能访问父类的private成员的
而且前面healer_kx说了,friend机制是不支持继承的
父类是某个类的friend,但它的子类也不能访问那个类的protected或private成员
suhuobing 2006-01-18
  • 打赏
  • 举报
回复
其实继承时public Chain< DD<T> >改成public Chain< T >
main.cpp用ChainChild<DD<T> > la;可以简化问题
但我很想知道用public Chain< DD<T> >继承能不能访问父类的私有成员
suhuobing 2006-01-18
  • 打赏
  • 举报
回复
还能不能解释一下Chain类和Node类里的friend class ChainChild<T>
改成friend class ChainChild<int>就可以在main.c里支持
ChainChild<int> la;
la.UseP();

改成friend class ChainChild<float>就支持
ChainChild<float> lb;
lb.UseP()

而friend class ChainChild<T>却对两个都不支持

zeusnchen 2006-01-18
  • 打赏
  • 举报
回复
>1 把继承类声明为父类的友元类,就可以访问父类的private成员了吧
当然可以
>2 本例中的父类并不是任何类的friend,我是把派生类,即ChainChild类声明为
问题是你的父类和子类使用了不同的模版参数
实例化后它们是不同的类!所以你的friend申明没有效果

具体点说,你的Chain<T>申明的friend类是ChainChild<T>, 而不是ChainChild< DD<T> >

如果你是想把一个template 类申明为friend(这样它的所有实例化的类都是friend)的话,
你应该这样:
template <class T> class Chain; //forward declaration

template <class T>
class ChainChild {
template <class T2> friend class Chain; //using a different typename as template parameter!!!
};

而不是:
template <class T> class Chain; //forward declaration

template <class T>
class ChainChild {
friend class Chian<T>; //here, Chain<T> is a concrete class!!!!!
};
suhuobing 2006-01-18
  • 打赏
  • 举报
回复
顶上去
a97191 2006-01-18
  • 打赏
  • 举报
回复
suhuobing 2006-01-18
  • 打赏
  • 举报
回复
to zeusnchen():
1 把继承类声明为父类的友元类,就可以访问父类的private成员了吧
2 本例中的父类并不是任何类的friend,我是把派生类,即ChainChild类声明为
Node类和Chain类的friend
LiuYinChina 2006-01-17
  • 打赏
  • 举报
回复
friend 机制不支持继承。
template <class T>
class Chain
{
friend class ChainChild<T>;
public:
Chain(){}
~Chain(){}
protected: //
Node<T> c;
};

template <class T>
class Node
{
friend class ChainChild<T>;
public:
Node(){}
~Node(){}

T & getData() { return data; }
void setData(const T &t) { data = t; }
private:
T data;
};

void UseP()
{
c;
c.getData();
}
suhuobing 2006-01-17
  • 打赏
  • 举报
回复
上面main.c应该是没有最后两句的,刚才弄错了
zeusnchen 2006-01-17
  • 打赏
  • 举报
回复
兄弟
看看实洌化后是什么样子哈
> template <class T>
> class ChainChild : public Chain< DD<T> > //这里DD<T>改成T就不会有问题
根据你的代码,实例化后,
Chain 的模版参数是 DD<T>,所以作为freind class的定义
只有 ChainChild < DD<T> > 才能访问它的私有成员,而不是 ChainChild <T>
同样对Node 也是一样的
这就是为什么把DD<T>改成<T>后可以编译通过了

BTW,用VC的话,很多时候会碰到莫名其妙的compiler错误,为了确保不是自己的错误,可以把类似的程序在G++下试试,才能知道是编译器的问题还是自己的问题
suhuobing 2006-01-17
  • 打赏
  • 举报
回复

suhuobing 2006-01-17
  • 打赏
  • 举报
回复
没人光顾,我自己顶一下先
suhuobing 2006-01-17
  • 打赏
  • 举报
回复
各位是否可以说得详细一点?
为什么ChainChild继承那里DD<T>改成T就可以?
还有一个现象就是Chain类和Node类里的friend class ChainChild<T>
改成friend class ChainChild<int>就可以在main.c里支持
ChainChild<int> la;la.UseP();
改成<float>就支持lb
加载更多回复(1)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧