【问题标题】:Using friend function in C++在 C++ 中使用友元函数
【发布时间】:2012-12-14 19:06:39
【问题描述】:

刚刚阅读了友元函数,我正在尝试使用 B 类的友元函数“打印”访问 A 类中的私有变量“数字”。我正在使用 Visual Studio。编译我的代码给了我很多各种错误,例如:

C2011: 'A' : 'class' 类型重新定义
C2653: 'B' : 不是类或命名空间名称

请耐心等待我,并展示实现我目标的正确方法。

这是我的文件 啊哈:

class A
{
public:
    A(int a);
    friend void B::Print(A &obj);
private:
    int number;
};

A.cpp:

#include "A.h"

A::A(int a)
{
    number=a;
}

B.h:

#include <iostream>
using namespace std;
#include "A.h"
class B
{
public:
    B(void);
    void Print(A &obj);
};

B.cpp:

#include "B.h"

B::B(void){}

void B::Print(A &obj)
{
    cout<<obj.number<<endl;
}

main.cpp:

#include <iostream>
#include <conio.h>
#include "B.h"
#include "A.h"

void main()
{
    A a_object(10);
    B b_object;
    b_object.Print(A &obj);
    _getch();
}

【问题讨论】:

  • 提示:B 类实际上不需要知道A 的详细信息,它只需要知道A存在。跨度>
  • 删除 friend void B::Print(A &amp;obj);,添加 friend class B; 或按照 Mooning Ducks 提示。
  • 在 B.h 中删除 #include "A.h" 并添加 class A; 然后在 B.cpp 中添加 #include "A.h"

标签: c++ class friend friend-class


【解决方案1】:

...其次,您可能需要在 A.h 头文件中对类 B 进行前向声明,以将 B 引用为朋友:

#ifndef _A_H_
#define _A_H_
class B;

class A
{
     friend class B;
};
#endif

更新
我目前不太确定是否可以将成员函数声明为好友,我会看看。

无法创建成员函数friend 声明,您可以将全局函数或整个类声明为友元,另请参见:C++ ref, Friendship and inheritance

一般来说,使用friend 根本不是一个好的设计理念,因为它将类强耦合在一起。更好的解决方案是耦合接口(无论如何都不需要公开可见)。
在极少数情况下,这可能是一个好的设计决策,但几乎总是适用于内部细节。

【讨论】:

  • 使用friend 并不总是坏事。见parashift.com/c++-faq/friends-and-encap.html
  • @FredLarson 是的,我提到了弗雷德。无论如何,它在 UML 中已被弃用,您通常可以使用抽象(纯虚拟)或静态(模板)接口来替换对 friend 声明的需求。这也可以让您对“朋友”类或方法可以访问的内容进行细粒度控制。
【解决方案2】:

首先你需要放

#ifndef A_H
#define A_H
.... your A-class definition
#endif

在您的 A.h 中和在 B.h 中类似,因此可以防止同一文件的多个包含(即您的重复定义错误)...

【讨论】:

  • 或者您可以将“#pragma once”放在 .h 文件的开头。
  • 不,请:删除双下划线。包含两个下划线的名称和以下划线后跟大写字母的名称保留给实现。不要使用它们。
  • @PRouleau 嗯。如果您在 Visual C++ 世界中。不确定 gcc 是否理解这一点?
  • 好吧,OP 没有提到代码应该是可移植的,它确实使用了 Visual Studio。至于 GCC,它确实理解它。见stackoverflow.com/questions/787533/…我更喜欢使用它,因为它是一行,没有机会与另一个头文件冲突。
  • 我要补充一点,OP 是从 C++ 开始的。他应该在哪里知道带下划线的#define 是保留的?我搜索了“c++ #define”,它的描述中没有指定。当然,任何好书或教程都会提到使用 include 守卫的重要性,但并不总是关于保留规则。
猜你喜欢
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多