友元函数体实现在类内和实现在类外的区别?

hi5000 2012-06-06 01:31:27

#include <iostream>

class A
{
public:
friend void f() {};
};

int main()
{
f();

system( "pause" );
return 0;
}


如果友元函数实现在类体内,main函数体内的f调用在编译的时候报错,error C3767: “f”: 候选函数不可访问。

请问:友元函数体实现在类内和实现在类外的区别,希望具体点的,多谢各位!

...全文
1394 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hi5000 2012-06-07
  • 打赏
  • 举报
回复
感谢supermegaboy!
tongzhipeng5699 2012-06-06
  • 打赏
  • 举报
回复
谢谢大侠!学习了!
[Quote=引用 9 楼 的回复:]

这个问题是个有趣的问题。

问题的答案是:类域内定义的友元函数调用时必须具有该类类型的实参。解释如下:

首先类域内定义的友元函数应该如何看待呢?C++标准的规定:

11.4 Friends

A function can be defined in a friend declaration of a class if and only if the class is a no……
[/Quote]
taodm 2012-06-06
  • 打赏
  • 举报
回复
我记得是herb sutter的文章,或者是《modern c++ design》讲的这个问题。
飞天御剑流 2012-06-06
  • 打赏
  • 举报
回复
这个问题是个有趣的问题。

问题的答案是:类域内定义的友元函数调用时必须具有该类类型的实参。解释如下:

首先类域内定义的友元函数应该如何看待呢?C++标准的规定:

11.4 Friends

A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8), the function name is unqualified, and the function has namespace scope. [Example:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};
—end example]
Such a function is implicitly inline. A friend function defined in a class is in the
(lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).


f不是qualified-id,但函数体本身处于类域构成的名称空间域内。这意味着,不能使用A::f这样的qualified-id,但调用时又必须体现一个qualified的函数体,这如何做到?还是标准的条款:

7.3.1.2 Namespace member definitions

If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).

当调用一个友元函数时,名字搜索域也包含与实参关联的那些名称空间和类中的名字,于是,一个如下定义的友元函数可以被调用:

friend void f( A& a ) {}

但是如果f的形参不是A类型的行不行呢?当然行,但必须具备有效的从A到f形参类型的转换,例如:


#include <iostream>

class A
{
public:
friend void f( int a ){ }

operator int( ){ return a; }

private:

int a;
};

int main( void )
{
A a;
f( a );
return 0;
}


除此之外都是非法调用。

依希记得C++ primer第三版谈过这个问题,但身边没有这书,有兴趣的朋友可以自行翻阅。
taodm 2012-06-06
  • 打赏
  • 举报
回复
去看herb sutter的“be friending templetes”
pathuang68 2012-06-06
  • 打赏
  • 举报
回复
友元函数不是成员函数,没有this指针。
pathuang68 2012-06-06
  • 打赏
  • 举报
回复
1. 友元函数必须在类内容声明,这一点应该没有疑问。
2. 一般情况下,友元函数是在类的外部定义的,但在类的内部定义也没有问题,所以说内外皆可。
大尾巴猫 2012-06-06
  • 打赏
  • 举报
回复

#include <iostream>

class A
{
public:
friend void f(const A & a) {}
};

int main()
{
A a;
f(a);

system( "pause" );
return 0;
}

qq120848369 2012-06-06
  • 打赏
  • 举报
回复
看书吧,友元和类成员函数是两码事.
tongzhipeng5699 2012-06-06
  • 打赏
  • 举报
回复 1
印象中觉得好像用友元定义在类里面的,所以以为楼上两位牛人莫非弄错了,结果一百度,还真的是里面声明,外面定义,然后自己写了一下,发现确实要类外定义,但是我找出以前的代码,再写了下面一个代码,我凌乱了...
求解释!..........

#include <iostream>
using namespace std;

// void f(void) {
//
// cout << "in global" << endl;

class A {
private:
int m_a;
public:
A(int n):m_a(n){}
friend ostream& operator<<(ostream& os,const A& a) {
return os<<a.m_a;
}
friend void f(const A& a) {
cout << "in class" << endl;
}
friend void f(void) {
cout << "in class void" << endl;
}
};


int main(void) {

A a(3);
cout << a << endl;
f();//编译错误
f(a);//正常运行,为什么啊?,顺便说一下,VC里面f()也能通过编译.
return 0;
}

[Quote=引用 2 楼 的回复:]

引用 1 楼 的回复:

friend function本质上来说还是global的,不是class scope的,所以只能在类里面声明,在类外面定义。

+++
[/Quote]
W170532934 2012-06-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

friend function本质上来说还是global的,不是class scope的,所以只能在类里面声明,在类外面定义。
[/Quote]
+++
ForestDB 2012-06-06
  • 打赏
  • 举报
回复
friend function本质上来说还是global的,不是class scope的,所以只能在类里面声明,在类外面定义。
关于的下列描述中,错误的是( )。
是一组对象的模板
是抽象数据的实现
是数据和方法的封装
是对象的实例
~D
关于对象的下列描述中,错误的是( )。
对象是一种
对象是的一个实例
对象是客观世界中的一种实
对象之间是通过消息进行通信的
~A
下列关于继承的描述中,正确的是( )。
继承不是之间的一种关系
C++语言仅支持单一继承
继承会增加程序的冗余性
继承是面向对象方法中一个很重要的特性
~D
关于的定义的描述中错误的是( )。
的定义格式分为说明部分和实现部分
中一般包含有成员函数和数据成员
中成员有3种访问权限
成员函数都是公有的,数据成员都是私有的
~D
关于中成员函数的描述中,错误的是( )。
中可以说明一个或多个成员函数
中的成员函数只能定义在
定义在外的成员函数前加inline可成为内联函数
外定义成员函数时,需用名和作用域运算符加以限定
~B
下列关于成员函数的特性描述中,错误的是( )。
成员函数可以重载
成员函数都是内联函数
成员函数可以设置参数的默认值
成员函数可以是公有的,也可以是私有的
~B
关于友元函数的描述中,错误的是( )。
友元函数不是成员函数
友元函数只能访问中私有成员
友元函数破坏隐蔽性,尽量少用
友元函数说明在内,使用关键字friend
~B
下列关于派生的描述中,错误的是( )。
派生至少应有一个基
目 录 序言 前言 第1章 程序设计与算法 1 1.1 程序设计语言的发展 1 1.2 C语言的特点 2 1.2.1 C语言是中级语言 2 1.2.2 C语言是结构化语言 3 1.2.3 C语言是程序员的语言 3 1.3 C语言的程序结构 4 1.3.1 基本程序结构 4 1.3.2 函数库和链接 6 1.3.3 开发一个C程序 7 1.3.4 C语言的关键字 7 1.4 算法 8 1.4.1 流程图与算法的结构化描述 9 1.4.2 用N-S图描述算法 12 1.4.3 用PAD图描述算法 13 第2章 数据型、运算符和表达式 14 2.1 C语言的数据型 14 2.2 常量与变量 15 2.2.1 标识符命名 15 2.2.2 常量 16 2.2.3 变量 16 2.3 整型数据 16 2.3.1 整型常量 16 2.3.2 整型变量 17 2.4 实型数据 18 2.4.1 实型常量 18 2.4.2 实型变量 18 2.5 字符型数据 19 2.5.1 字符常量 19 2.5.2 字符串常量 19 2.5.3 转义字符 20 2.5.4 符号常量 20 2.5.5 字符变量 21 2.6 运算符 22 2.6.1 算术运算符 22 2.6.2 自增和自减 22 2.6.3 关系和逻辑运算符 23 2.6.4 位操作符 24 2.6.5 ?操作符 26 2.6.6 逗号操作符 27 2.6.7 关于优先级的小结 27 2.7 表达式 28 2.7.1 表达式中的型转换 28 2.7.2 构成符cast 29 2.7.3 空格与括号 29 2.7.4 C语言中的简写形式 29 第3章 程序控制语句 31 3.1 程序的三种基本结构 31 3.2 数据的输入与输出 31 3.2.1 scanf()函数 31 3.2.2 printf()函数 33 3.2.3 getchar()函数与putchar()函数 36 3.2.4 程序应用举例 37 3.3 条件控制语句 38 3.3.1 if 语句 38 3.3.2 switch 语句 43 3.3.3 程序应用举例 45 3.4 循环控制语句 46 3.4.1 while语句 47 3.4.2 do... while 语句 49 3.4.3 for 语句 50 3.4.4 break与continue语句 53 3.4.5 程序应用举例 54 第4章 函数 57 4.1 函数说明与返回值 57 4.1.1 函数的型说明 57 4.1.2 返回语句 58 4.2 函数的作用域规则 60 4.2.1 局部变量 60 4.2.2 全局变量 61 4.2.3 动态存储变量 62 4.2.4 静态存储变量 63 4.3 函数的调用与参数 63 4.3.1 形式参数与实际参数 64 4.3.2 赋值调用与引用调用 64 4.4 递归 64 4.5 实现问题 66 4.5.1 参数和通用函数 66 4.5.2 效率 66 4.6 函数库和文件 67 4.6.1 程序文件的大小 67 4.6.2 分组织文件 67 4.6.3 函数库 67 4.7 C语言的预处理程序与注释 67 4.7.1 C语言的预处理程序 68 4.7.2 #define 68 4.7.3 #error 69 4.7.4 # include 69 4.7.5 条件编译命令 70 4.7.6 #undef 72 4.7.7 #line 73 4.7.8 #pragma 73 4.7.9 预定义的宏名 73 4.7.10 注释 73 4.8 程序应用举例 74 第5章 数组 78 5.1 一维数组 78 5.1.1 向函数传递一维数组 78 5.1.2 字符串使用的一维数组 79 5.2 二维数组 80 5.2.1 二维数组的一般形式 80 5.2.2 字符串数组 84 5.3 多维数组 85 5.4 数组的初始化 85 5.4.1 数组初始化 85 5.4.2 变长数组的初始化 86 5.5 应用程序举例 87 第6章 指针 91 6.1 指针与指针变量 91 6.2 指针变量的定义与引用 92 6.2.1 指针变量的定义 92 6.2.2 指针变量的引用 93 6.3 指针运算符与指针表达式 94 6.3.1 指针运算符与指针表达式 94 6.3.2 指针变量作函数的参数 95 6.4 指针与数组 96 6.4.1 指针与一维数组 97 6.4.2 指针与二维数组 99 6.4.3 数组指针作函数的参数 102 6.4.4 指针与字符数组 108 6.5 指针的地址分配 111 6.6 指针数组 112 6.7 指向指针的指针 118 6.8 main函数的参数 121 第7章 结构与共用 125 7.1 结构型变量的定义和引用 125 7.1.1 结构型变量的定义 126 7.1.2 结构型变量的引用 127 7.1.3 结构型变量的初始化 127 7.2 结构数组的定义和引用 129 7.3 结构指针的定义和引用 135 7.3.1 指向结构型变量的使用 135 7.3.2 指向结构型数组的指针的 使用 136 7.4 链表的建立、插入和删除 138 7.4.1 单链表 139 7.4.2 单链表的插入与删除 141 7.5 共用 149 7.5.1 共用的定义 149 7.5.2 共用变量的引用 150 第8章 输入、输出和文件系统 153 8.1 缓冲文件系统 153 8.1.1 文件的打开与关闭 153 8.1.2 文件的读写 155 8.1.3 随机读写文件 163 8.2 非缓冲文件系统 166 8.3 文件系统应用举例 167 第9章 实用编程技巧 170 9.1 图形应用技巧 170 9.1.1 显示适配器型的自动测试 170 9.1.2 屏幕图像的存取技巧 179 9.1.3 屏幕显示格式的控制方法 181 9.1.4 使图形软件脱离BGI的方法 182 9.1.5 拷贝屏幕图形的方法 183 9.1.6 随意改变VGA显示器显示颜色的 技巧 185 9.1.7 用随机函数实现动画的技巧 187 9.1.8 用putimage 函数实现动画的技巧 189 9.2 菜单设计技术 191 9.2.1 下拉式菜单的设计 191 9.2.2 选择式菜单的设计 194 9.2.3 实现阴影窗口的技巧 195 9.3 音响技巧 197 9.3.1 音乐程序设计 197 9.3.2 自动识谱音乐程序 200 9.3.3 实现后台演奏音乐的技巧 203 第10章 C++入门 205 10.1 面向对象的概念 205 10.1.1 面向对象的程序结构 205 10.1.2 C++的 206 10.2 C++的输入与输出 207 10.3 与对象 208 10.3.1 的定义与对象的引用 209 10.3.2 构造函数与析构函数 211 10.3.3 函数重载 215 10.3.4 友元 216 10.4 对象指针 219 10.5 派生与继承 225 10.5.1 单继承的派生 225 10.5.2 多继承的派生 233 附录A 常用字符与ASCII代码对照表 238 附录B 习题 239

64,654

社区成员

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

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