Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在朋友类中包含头文件_C++_Class_Friend - Fatal编程技术网

C++ 在朋友类中包含头文件

C++ 在朋友类中包含头文件,c++,class,friend,C++,Class,Friend,我想知道你是否必须将“Class1.h”包含在一个将其用作朋友的类中。例如,授予Class1类权限的类的.h文件 class Class2 { friend class Class1; } 您需要包括“Class1.h”还是不需要?同样在Class2类中,永远不会创建或使用Class1对象。Class1只是操纵Class2,而不是相反。语法是: friend class Class1; 不,你不包括标题 更一般地说,您不需要包含头,除非您实际以某种方式使用了类定义(例如,您使用了类的实

我想知道你是否必须将“Class1.h”包含在一个将其用作朋友的类中。例如,授予Class1类权限的类的.h文件

class Class2 {
   friend class Class1;
}
您需要包括“Class1.h”还是不需要?同样在Class2类中,永远不会创建或使用Class1对象。Class1只是操纵Class2,而不是相反。

语法是:

friend class Class1;
不,你不包括标题

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

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


要回答Gary的评论,请注意这可以很好地编译和链接:

class X;

class Y
{
    X *x;
};

int main()
{
    Y y;
    return 0;
}
没有必要提供X的定义,除非您实际使用X中的某些内容。

不,您不必“将”Class1.h“包含在将其用作朋友的类中”。您甚至不必向前声明
类Class1
的存在。您只需在Class2的定义中将Class1声明为好友,就这样!(我假设
friend class Class1
语句本身就是
Class1
的一种“转发声明”:

这里有一个完整的、有效的例子。可以(请注意,运行此示例时有两个选项卡——每个文件一个)

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;
};
#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;
}
main.cpp

#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;
};
#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;
}
#包括“Class2.h”
#包括
一班
{
公众:
int getClass2Int()
{
返回_class2._myInt;
}
void setClass2Int(int val)
{
_类别2._myInt=val;
}
私人:
类别2(u类别2);;
};
int main()
{
printf(“Hello World\n”);
1类;
printf(“class1.getClass2Int()=%i\n”,class1.getClass2Int());
class1.setClass2Int(700);
printf(“class1.getClass2Int()=%i\n”,class1.getClass2Int());
返回0;
}
输出:

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

参考资料:
  • 谷歌搜索

  • 只要类最终包含在同一个二进制文件中(否则在链接过程中会出现错误)@GaryRobinson:只有尝试执行实际需要类定义的操作时,才会出现链接错误。试试看,就像一个想象中的朋友:)我从来没有试过不,这也许是一个很有针对性的理论,但我假设提问者实际上会在某些情况下使用一个friend类way@GabrielStaples如下文所述,我想你可能误解了我所说的“更普遍”的意思——我的意思是还有其他情况,当您将一个类声明为友元时除外,在友元中,您可能同样没有使用类定义,但仍然需要向编译器声明该类。friend声明确实充当了类的声明(您不需要另一个单独的声明),但这不是我想说的重点。我明白了。现在这是有道理的。谢谢。我只是想澄清一下,“更一般地”指的是“即使你没有让班级成为朋友”——也就是说,在你没有使用班级定义的任何情况下,包括这个情况。这并不意味着在声明类为好友时,除了需要转发声明类之外,还需要转发声明类。我明白了。我修改了我的答案,删除了对你答案的提及。我认为我的答案仍然非常有用,可以作为一个完整的例子来说明如何做到这一切。