在作为朋友的类中包含头文件

Posted

技术标签:

【中文标题】在作为朋友的类中包含头文件【英文标题】:Including header file in class that is a friend 【发布时间】:2012-04-11 20:23:19 【问题描述】:

我想知道您是否必须在使用它作为朋友的类中#include "Class1.h"。例如,授予 Class1 类权限的类的 .h 文件。

class Class2 
   friend class Class1;

您需要#include "Class1.h" 还是不需要?同样在 Class2 类中,从未创建或使用 Class1 对象。 Class1 只是操纵 Class2 而不是相反。

【问题讨论】:

【参考方案1】:

语法是:

friend class Class1;

不,你不包括标题。

更一般地说,您不需要包含标头,除非您实际上以某种方式使用类定义(例如,您使用类的实例并且编译器需要知道其中的内容)。如果您只是按名称引用该类,例如你只有一个指向类实例的指针并且你正在传递它,然后编译器不需要查看类定义 - 通过声明它就足以告诉它类:

class Class1;

这很重要有两个原因:次要的一个是它允许您定义相互引用的类型(但您不应该!);主要的一点是它可以让您减少代码库中的物理耦合,这有助于减少编译时间。


要回答 Gary 的评论,请注意编译和链接是否正常:

class X;

class Y

    X *x;
;

int main()

    Y y;
    return 0;

除非您实际使用 X 中的某些东西,否则无需提供 X 的定义。

【讨论】:

只要类最终包含在同一个二进制文件中(否则在链接过程中会出错) @GaryRobinson:如果您尝试执行实际需要类定义的操作,您只会收到链接错误。试试看。 什么是想象中的朋友 :) 我从来没有尝试过,这可能是一个很好的尖锐理论,但我假设提问者会以某种方式实际使用朋友类跨度> @GabrielStaples 如下所述,我认为您可能误解了我所说的“更普遍”的意思-我的意思是,除了您将班级声明为朋友之外,还有其他情况您同样可能没有使用类定义,但仍需要向编译器声明该类。朋友声明确实充当了类的声明(您不需要另一个单独的声明),但这不是我想要说明的重点。 我明白了。现在这是有道理的。谢谢。【参考方案2】:

不,您确实必须“#include "Class1.h" 在一个使用它作为朋友的类中。”您甚至不必转发声明class Class1 的存在。您只需在 Class2 的定义中声明 Class1 为友元即可! (我想friend class Class1 语句本身就是Class1 的一种“前向声明”):

// Inside the definition of Class2, place this (usually
// at the very bottom inside the `private:` section)
friend class Class1;

这是一个完整的工作示例。您可以run and test it here(请注意,运行此示例时有 2 个选项卡——每个文件一个)。

Class2.h

#pragma once 

class Class2

private:
    int _myInt = 123;

    // Declare Class1 as a friend class to Class2 so that Class1 can access all of Class2's private
    // and protected members (as though Class2's members were part of Class1)
    friend class Class1;
;

ma​​in.cpp

#include "Class2.h"

#include <stdio.h>

class Class1

public:
    int getClass2Int()
    
        return _class2._myInt;
    

    void setClass2Int(int val)
    
        _class2._myInt = val;
    

private:
    Class2 _class2;
;

int main()

    printf("Hello World\n");

    Class1 class1;

    printf("class1.getClass2Int() = %i\n", class1.getClass2Int());
    class1.setClass2Int(700);
    printf("class1.getClass2Int() = %i\n", class1.getClass2Int());

    return 0;

输出:

你好世界 class1.getClass2Int() = 123 class1.getClass2Int() = 700

参考资料:

    https://www.geeksforgeeks.org/friend-class-function-cpp/ 谷歌搜索"do you need to include header file to declare friend class?" Including header file in class that is a friend

【讨论】:

澄清一下,“更一般地”指的是“即使你没有让班级成为朋友”——即在你没有使用班级定义的任何情况下,包括这个。这并不意味着您需要转发声明该类除了当您声明它是朋友时这样做。 我明白了。我已经修改了我的答案以删除对您的答案的提及。我认为我的回答作为如何做到这一切的完整示例仍然非常有用。

以上是关于在作为朋友的类中包含头文件的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSQL C 扩展中包含头文件

vS 2008 中包含头文件vector的问题:

如何在 Qt Creator 的 CMakeLists.txt 中包含头文件?

visualstudio2022怎么在新建项中包含头文件

在 C++ 中包含头文件时尖括号 < > 和双引号“”之间的区别? [复制]

不能在vsi2017的linux子系统中包含头文件