C+中的朋友声明+; 在布鲁斯的ECKEL C++思想中,有一个关于朋友函数的例子: // Declaration (incomplete type specification): struct X; struct Y { void f(X*); }; struct X { // Definition private: int i; public: friend void Y::f(X*); // Struct member friend }; void Y::f(X* x) { x->i = 47; }

C+中的朋友声明+; 在布鲁斯的ECKEL C++思想中,有一个关于朋友函数的例子: // Declaration (incomplete type specification): struct X; struct Y { void f(X*); }; struct X { // Definition private: int i; public: friend void Y::f(X*); // Struct member friend }; void Y::f(X* x) { x->i = 47; },c++,declaration,friend,C++,Declaration,Friend,现在他解释说: 请注意,Y::f(X*)取X的地址 对象这是至关重要的,因为编译器总是知道如何 传递一个地址,该地址大小固定,与对象无关 被传递,即使它没有关于大小的完整信息 是那种类型的。但是,如果尝试传递整个对象,则 编译器必须看到X的整个结构定义,才能知道 在它允许您声明函数之前,大小和如何传递它 例如Y::g(X) 但是当我试着 void f(X); 作为struct Y中的声明,它没有显示错误。 请解释原因?问题在于更改struct X中的声明时 因此,在struct X内部,您

现在他解释说:

请注意,Y::f(X*)取X的地址 对象这是至关重要的,因为编译器总是知道如何 传递一个地址,该地址大小固定,与对象无关 被传递,即使它没有关于大小的完整信息 是那种类型的。但是,如果尝试传递整个对象,则 编译器必须看到X的整个结构定义,才能知道 在它允许您声明函数之前,大小和如何传递它 例如Y::g(X)

但是当我试着

void f(X);  
作为struct Y中的声明,它没有显示错误。
请解释原因?

问题在于更改struct X中的声明时

因此,在struct X内部,您告诉编译器struct有一个函数,该函数接收X类型的内容,但请稍候,此时还没有完全定义X类型

不能使用不完整类型作为函数f的参数,但可以使用不完整类型的地址,因此X*


在网站上,提高你的接受率对你来说非常重要,这样你就可以为你未来的问题找到答案,如果我得到了正确的答案,这对我的自我也很重要:)

通过值传递不完整的对象
X
,应该没问题,尽管在函数实现过程中,无论函数中是否实际使用了
X
类型的对象,完整的
X
类型都必须可用。
函数声明可以使用不完整对象作为参数或返回类型,但协变返回类型(对于成员函数)除外,协变返回类型必须是完整类型。

函数声明的参数类型可能不完整

但是,对于数据成员声明和所有定义,类型必须完整:

struct A;
struct B {
    void f(A);   // declaration, fine
    void g(A) {} // error
    A a;         // error
};

是的,我知道我们不能使用不完整的类型作为函数的参数,但是当我在结构Y中将函数声明为void f(X)时;在struct X中,我写friend void Y::f(X);那么就没有错误了。这是怎么允许的?谢谢,但他解释的最后一行表明,我们甚至不能宣布f(X)为无效;只有在函数定义过程中,当X通过值传递时,编译器才需要知道X类型的对象的大小,以便它可以设置本地堆栈,而不管该值是否正在使用。而对于引用或指针类型,编译器知道指针/引用的大小,因此只要不访问对象x的任何成员,就可以实现该函数。如果需要访问x的成员,则需要提供完整类型的x。可能这本书想说的是,由于X是不完整类型,所以不可能实现给定的f(X*)。