如何实现一个类函数声明为另一个类的友元,并且两个类在不同的文件中, 举例如下:
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现一个类函数声明为另一个类的友元,并且两个类在不同的文件中, 举例如下:相关的知识,希望对你有一定的参考价值。
//A.h
class A
private:
int val_a;
friend void B::GetValueA(A *pA);
...
//A.cpp
#include"A.h"
...
//B.h
class B
private:
int val_b;
void GetValueA(A *pA);
//B.cpp
#include"B.h"
void B::GetValueA(A *pA)
val_b = pA->val_A;
//main.cpp
#include"A.h"
#include"B.h"
......
谢谢各位!!!
在A.h文件里面 class A 出现的前面加上
extern class B;
这句话的意思是,这里需要一个B 类的声明,而B类不在当前文件中,需要在其他文件找
同理 你还需要在 B.h 中加入
extern class A;
又因为在B.cpp中用到 A类的实现,所以要加上
#include "A.h"
修改后:
//A.h
extern class B; //////////////////////添加
class A
private:
int val_a;
friend void B::GetValueA(A *pA);
...
//A.cpp
#include"A.h"
...
//B.h
extern class A; ///////////////////添加
class B
private:
int val_b;
void GetValueA(A *pA);
//B.cpp
#include "A.h" ///////////////////添加
#include"B.h"
void B::GetValueA(A *pA)
val_b = pA->val_A;
//main.cpp
#include"A.h"
#include"B.h"
......追问
我按照您说的方法进行了尝试,但是编译仍然不能通过,问题在于A.h中 extern class B并不能让编译器知道B的成员函数有哪些,所以会报 使用了未定义类型B的错误,不过仍然感谢您
参考技术A #ifndef C_H_#define C_H_
#include "D.h"
class C
int m_i;
public:
C(int i);
~C();
friend void D::foo(C& c);
;#include "C.h"
C::C(int i)
m_i = i;
C::~C()
#ifndef D_H_
#define D_H_
class C;
class D
public:
void foo(C& c);
;
#endif /* D_H_ */#include <iostream>
#include "C.h"
#include "D.h"
void D::foo(C& c)
std::cout << c.m_i << std::endl;
#include "C.h"
#include "D.h"
int main(void)
C c(222);
D d;
d.foo(c);
return 0;
本回答被提问者采纳 参考技术B 可以吧,但是可能得在A.h里面加上 #include B.h, 在B.h里面加上#include A.h
为啥 PRIVATE 成员函数不能成为另一个类的友元函数?
【中文标题】为啥 PRIVATE 成员函数不能成为另一个类的友元函数?【英文标题】:Why can't a PRIVATE member function be a friend function of another class?为什么 PRIVATE 成员函数不能成为另一个类的友元函数? 【发布时间】:2015-01-13 09:21:45 【问题描述】:class x
void xx()
;
class y
friend void x::xx();
;
这会导致类似
的错误错误:友元函数“xx”是“x”的私有成员
为什么我不能将私有成员函数声明为另一个类的友元?
【问题讨论】:
Friend declaration in C++ - difference between public and private 的可能重复项 @hagubear 绝对不是那个副本。 您是在问为什么语言不允许这样做吗?在某些时候,有人认为(可以理解)这是一个坏主意。 因为否则它不会是私有的。 【参考方案1】:[class.friend]/9:
朋友声明指定的名称应可在 包含朋友声明的类的范围。
原因很简单; private
会员必须遵守明确的规则:
一个类的成员可以是
private
;也就是说,它的名称只能被声明它的类的成员和朋友使用。
允许在不相关类的声明中命名私有成员将违反此规则:它允许另一个类依赖于实现细节而无需明确允许。例如,当更改私有成员的名称、类型或签名,或完全删除它时,这会成为问题;这是为了不破坏该类的接口。
这可以通过将整个x
设为y
的朋友来规避:
class x
void xx()
;
class y
friend x;
;
Demo.
【讨论】:
可能我没看懂问题,但不应该是相反的方式,就是让y
成为x
的朋友吗?在您的示例中,y
将无法访问 x
的私有方法。
@IvanSmirnov 最初的 sn-p 的意图是允许x
的成员访问y
的私人数据。
啊,对,不是最直观的东西。谢谢,知道了。
@IvanSmirnov 您建议的是 hvd 下面的方法,这似乎是不必要的复杂。【参考方案2】:
制作x::xx
private
的想法应该是x::xx
是其他类不应该依赖的实现细节。这不仅仅意味着 x::xx
不能被其他类调用,它意味着,或者更确切地说,它应该意味着,例如将 x::xx
重命名为 x::xy
不应该破坏班级本身和班级朋友以外的任何内容。
在您的情况下,将 x::xx
重命名为 x::xy
会导致类 y
出现错误,即使它不是 x
的朋友。
避免这种情况的一种方法是让y
成为x
的朋友,以便y
可以访问x
的private
成员。然后它可以将x::xx
声明为friend
。
(注意:对于“为什么编译器不允许这个?”这个问题更直接的回答是“因为标准不允许这个。”,这自然会引出后续问题“为什么标准不允许这个。”允许这个吗?”。我正在尝试回答这个后续问题。)
【讨论】:
我可以拥有一个私有的虚拟成员函数,并在子类中被覆盖。在基类中重命名该虚函数会破坏某些东西,不是吗?` 我喜欢你所回答的问题究竟的区别。 @Columbo 你是对的。这是“它意味着”和“它应该意味着”之间的区别之一。 :) 顺便说一句。你解决这个问题的方法很奇怪。让整个班级y
成为x
的朋友,以便能够与x
的成员成为朋友?为什么要绕道?
@Columbo 这取决于具体情况。通常,当然,只需将所有 x
设为 y
的朋友即可。这是显而易见的解决方案。但是,如果 x
是一个有很多功能的大类,而 y
是一个小助手类,那么让 y
和 x::xx
成为朋友远比让所有 x
成为朋友更具侵略性。以上是关于如何实现一个类函数声明为另一个类的友元,并且两个类在不同的文件中, 举例如下:的主要内容,如果未能解决你的问题,请参考以下文章