如何实现一个类函数声明为另一个类的友元,并且两个类在不同的文件中, 举例如下:

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"
......
谢谢各位!!!

利用一下extern关键词就可以了,

在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::xxprivate的想法应该是x::xx是其他类不应该依赖的实现细节。这不仅仅意味着 x::xx 不能被其他类调用,它意味着,或者更确切地说,它应该意味着,例如将 x::xx 重命名为 x::xy 不应该破坏班级本身和班级朋友以外的任何内容。

在您的情况下,将 x::xx 重命名为 x::xy 会导致类 y 出现错误,即使它不是 x 的朋友。

避免这种情况的一种方法是让y 成为x 的朋友,以便y 可以访问xprivate 成员。然后它可以将x::xx 声明为friend

(注意:对于“为什么编译器不允许这个?”这个问题更直接的回答是“因为标准不允许这个。”,这自然会引出后续问题“为什么标准不允许这个。”允许这个吗?”。我正在尝试回答这个后续问题。)

【讨论】:

我可以拥有一个私有的虚拟成员函数,并在子类中被覆盖。在基类中重命名该虚函数会破坏某些东西,不是吗?` 我喜欢你所回答的问题究竟的区别。 @Columbo 你是对的。这是“它意味着”和“它应该意味着”之间的区别之一。 :) 顺便说一句。你解决这个问题的方法很奇怪。让整个班级y 成为x 的朋友,以便能够与x 的成员成为朋友?为什么要绕道? @Columbo 这取决于具体情况。通常,当然,只需将所有 x 设为 y 的朋友即可。这是显而易见的解决方案。但是,如果 x 是一个有很多功能的大类,而 y 是一个小助手类,那么让 yx::xx 成为朋友远比让所有 x 成为朋友更具侵略性。

以上是关于如何实现一个类函数声明为另一个类的友元,并且两个类在不同的文件中, 举例如下:的主要内容,如果未能解决你的问题,请参考以下文章

C++友元类

C++友元类

C++友元类

友元的友元类

基类和派生类的友元函数

C++之:友元类