问大家一个关于友元函数的问题

CHID 2010-12-03 11:19:21

#include "map"
#include "iostream"
#include "afxwin.h"

using namespace std;

//使用友元函数,控制只有类Container的AddElement函数可以修改类Element的ElementIndex属性,其他类在不能修改类Element的ElementIndex属性
//可是在编译时提示“error C2027: use of undefined type 'Container'”
//请问问题在哪,怎么修改?


//对Container类的提前引用声明
class Container;

class Element
{
public:
Element(){};
~Element(){};

CString Name;
CString Value;
public:
//返回元素在容器中的序号
int GetElementIndex()
{
return mElementIndex;
}

// //设置元素在容器中的序号
// void SetElementIndex(int ElementIndex)
// {
// mElementIndex=ElementIndex;
// }

friend void Container::AddElement(Element Data);
private :
int mElementIndex;
};

class Container
{
public:

Container()
{
mCount=0;
}
~Container(){};

//获取元素个数
int GetElementCount()
{
return mCount;
}

//根据名称获取元素对象
Element& GetElement(int index)
{
return mMap[index];
}

//增加元素
void AddElement(Element Data)
{
//Data.SetElementIndex(mCount) ;
//访问Element的私有变量
Data.mElementIndex=mCount;

mMap.insert(pair<int,Element>(mCount,Data)) ;
mCount=mCount+1;
}

private:
int mCount;
map<int,Element> mMap;
};



int main()
{
Element eltA,eltB,eltC;
Container ctn;

eltA.Name="Element_A";
eltA.Value="100";
eltB.Name="Element_B";
eltB.Value="200";
eltC.Name="Element_B";
eltC.Value="300";
ctn.AddElement(eltA) ;
ctn.AddElement(eltB) ;
ctn.AddElement(eltC) ;

for (int i=0;i<ctn.GetElementCount();i++)
{
cout<<(LPCTSTR)ctn.GetElement(i).Name<<" "<<(LPCTSTR)ctn.GetElement(i).Value<<endl;
}
return 0;
}
...全文
171 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
CHID 2010-12-03
  • 打赏
  • 举报
回复
感谢hnuqinhuan和jiadayang,这里希望控制只有类Container的AddElement函数可以修改类Element的ElementIndex属性。如果使用友元类的话,应该是类Container的其他函数也可以修改类Element的ElementIndex属性,达不到目的。
感谢pengzhixi,编译时上面的代码报错“error C2079: 'second' uses undefined class 'Element'”。
pengzhixi 2010-12-03
  • 打赏
  • 举报
回复
class Element;
class Container
{
public:

Container()
{
mCount=0;
}
~Container(){};

//获取元素个数
int GetElementCount()
{
return mCount;
}

//根据名称获取元素对象
Element& GetElement(int index)
{
return mMap[index];
}

//增加元素
void AddElement(Element *Data);
private:
int mCount;
map<int,Element> mMap;
};



class Element
{
public:
Element(){};
~Element(){};

string Name;
string Value;
public:
//返回元素在容器中的序号
int GetElementIndex()
{
return mElementIndex;
}

// //设置元素在容器中的序号
// void SetElementIndex(int ElementIndex)
// {
// mElementIndex=ElementIndex;
// }

friend void Container::AddElement(Element *Data);
private :
int mElementIndex;
};
void Container::AddElement(Element *Data){
//Data.SetElementIndex(mCount) ;
//访问Element的私有变量
Data->mElementIndex=mCount;

mMap.insert(pair<int,Element>(mCount,*Data)) ;
mCount=mCount+1;
}





int main()
{
Element eltA,eltB,eltC;
Container ctn;

eltA.Name="Element_A";
eltA.Value="100";
eltB.Name="Element_B";
eltB.Value="200";
eltC.Name="Element_B";
eltC.Value="300";
ctn.AddElement(&eltA) ;
ctn.AddElement(&eltB) ;
ctn.AddElement(&eltC) ;

for (int i=0;i<ctn.GetElementCount();i++)
{
cout<<ctn.GetElement(i).Name<<" "<<ctn.GetElement(i).Value<<endl;
}

system("pause");
return 0;

}
不过我将CString 改成了string
qq120848369 2010-12-03
  • 打赏
  • 举报
回复

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

class A;

class B
{
public:
void dosth()
{
}

public:
map<int,A> a;
};

class A
{
friend void B::dosth();
};

int main()
{
B b;
b.a[1]=A();

return 0;
}

楼主的情况修改后是这样,我不改你代码了,对照理解一下.
qq120848369 2010-12-03
  • 打赏
  • 举报
回复
楼主的设计互相嵌套了,而且Element里声明Container里的函数为友元,就必须在Elment类之前见到Container完整的类定义,而不是前置声明.

即便调换了两个类的次序,由于Container里用到了Element,所以你还需要在Contatiner前作Element的前置声明,并且修改Element里的函数形参为引用或者指针Container.
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jiadayang 的回复:]
友元类!
[/Quote]
具体怎么实现?
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hnuqinhuan 的回复:]
friend void Container::AddElement(Element Data);
友元没有这么声明的
你这是要表达什么意思啊
[/Quote]
希望控制只有类Container的AddElement函数可以修改类Element的ElementIndex属性,其他类在不能修改类Element的ElementIndex属性。但其他类可以访问Element的其他函数。
只要实现目的即可,怎么实现?
明月生寒 2010-12-03
  • 打赏
  • 举报
回复
友元类!
無_1024 2010-12-03
  • 打赏
  • 举报
回复
用友元类就可以实现这样的功能了
無_1024 2010-12-03
  • 打赏
  • 举报
回复
friend void Container::AddElement(Element Data);
友元没有这么声明的
你这是要表达什么意思啊
joey_zoy 2010-12-03
  • 打赏
  • 举报
回复
直接用友元类
friend class Container;
herman~~ 2010-12-03
  • 打赏
  • 举报
回复
比较简单的方法,还是买本C++ primer在身边,发现有问题的时候直接翻下吧
pengzhixi 2010-12-03
  • 打赏
  • 举报
回复
只要类声明顺序,成员函数定义顺序正确就没问题。
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 pengzhixi 的回复:]
你把我的代码改成非指针和非引用形式编译下就OK 了,为什么一定要别人告诉你呢
[/Quote]

已改为非指针和非引用形式,编译通过,运行正常。
不过刚好qq120848369提到这个问题,担心改为非指针和非引用形式,会有随机不可意料的错误出现。
各位能否讲解一下?
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 pengzhixi 的回复:]
你把我的代码改成非指针和非引用形式编译下就OK 了,为什么一定要别人告诉你呢
[/Quote]
已改为非指针和非引用的方式,可以运行,没有报错。
只是qq120848369刚好提到这一点,担心这么做会有随机不可意料的错误发生。
请各位帮忙讲解一下。
pengzhixi 2010-12-03
  • 打赏
  • 举报
回复
你把我的代码改成非指针和非引用形式编译下就OK 了,为什么一定要别人告诉你呢
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qq120848369 的回复:]
楼主的设计互相嵌套了,而且Element里声明Container里的函数为友元,就必须在Elment类之前见到Container完整的类定义,而不是前置声明.

即便调换了两个类的次序,由于Container里用到了Element,所以你还需要在Contatiner前作Element的前置声明,并且修改Element里的函数形参为引用或者指针Container.
[/Quote]
------------------------------------------------------------
再问一个问题:
如果Element里的函数形参不是 引用或者指针 行不行,会发生什么后果?
CHID 2010-12-03
  • 打赏
  • 举报
回复
结贴,多谢各位。
pengzhixi 2010-12-03
  • 打赏
  • 举报
回复
vc6.0本身对友元的支持不够
CHID 2010-12-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 pengzhixi 的回复:]
呵呵,我都没用到什么second
[/Quote]
VC6.0报错,换成VS2005不报错。
pengzhixi 2010-12-03
  • 打赏
  • 举报
回复
呵呵,我都没用到什么second

65,186

社区成员

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

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