3

在 Bruce eckel 的 Thinking in 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;
}

现在他解释了这一点:

请注意,Y::f(X*) 采用 X 对象的地址。这一点很关键,因为编译器总是知道如何传递一个地址,不管传递的对象是什么,这个地址都是固定大小的,即使它没有关于类型大小的完整信息。但是,如果您尝试传递整个对象,编译器必须先查看 X 的整个结构定义,以了解大小以及如何传递它,然后才能允许您声明诸如 Y::g(X) 之类的函数。

但是当我尝试

void f(X);  

作为 struct Y 中的声明,它没有显示错误。请解释为什么?

4

3 回答 3

1

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

于 2010-05-04T17:57:48.450 回答
1

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

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

struct A;
struct B {
    void f(A);   // declaration, fine
    void g(A) {} // error
    A a;         // error
};
于 2010-05-04T18:00:25.443 回答
0

问题是当您更改 struct X 中的声明时。

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

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

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

于 2010-05-04T17:45:48.333 回答