【发布时间】:2021-01-27 14:50:32
【问题描述】:
我环顾四周,寻找在 C++ 编译器中选择我所谓的虚构朋友的理由。不幸的是,我没有找到任何解释,所以我请教专家。
我想知道为什么 C++ 不抱怨以下代码。类和方法作为朋友表示实际上并不存在,但是如果你编译程序它就会编译并运行。
#include <iostream>
class TrueFriend
{
friend class NotExistingClass;
friend class AnotherNotExistingClass;
friend int NotExistingFunc();
public:
void TellAboutYou() { std::cout << "I have a lot of friends" << std::endl; }
};
int main(int argc, char **argv)
{
TrueFriend instance;
instance.TellAboutYou();
return 0;
}
【问题讨论】:
-
转发声明一个类型然后不定义它,如果你不实际使用该类型,不会导致我使用的编译器出错。
-
我觉得关键字
friend在这里并不重要,没有它你也可以这样做godbolt link。 -
一种思考方式是回想 C++ 一次编译一个翻译单元,而不知道其他翻译单元的内容。
friend class NotExistingClass;是一个前向声明,基本上说“当你开始编译NotExistingClass时,它是TrueFriend的friend。”但是当您在一个文件中编译TrueFriend时,它应该如何知道您是在其他文件中最终 还是从不 编译NotExistingClass?答案是它不知道也不必关心,所以它不关心。 -
这些声明与其说是“这个存在,而且是我的朋友”,不如说是“如果这个存在,那就是我的朋友”。 (顺便说一句,声明一个你从未定义过的类型非常有用。)
-
@NathanPierson 是正确的,但我的示例是一个可执行文件,因此它也将通过链接阶段。这对我来说似乎很奇怪,而且碰巧这样的代码只是混杂着无用的信息,使得代码难以阅读。