在Bruce 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;
}
现在他解释了这个:
注意Y :: f(X *)取X的地址 宾语。这很关键,因为编译器总是知道如何操作 传递一个固定大小的地址,无论该对象如何 被传递,即使它没有关于大小的完整信息 这种类型。但是,如果你试图传递整个对象,那么 编译器必须看到X的整个结构定义,才能知道 大小以及如何传递它,然后才允许您声明一个函数 例如Y :: g(X)。
但是当我尝试
时void f(X);
作为struct Y中的声明,它没有显示错误。 请解释原因?
答案 0 :(得分:1)
按值传递不完整的对象X
应该没问题,但在函数实现期间,无论X
类型的对象是否实际存在,完整类型X
都必须可用用于功能与否。
函数声明可以很好地使用不完整的对象作为参数或返回类型,除了协变返回类型(对于成员函数),其中这样的返回类型必须是完整类型。
答案 1 :(得分:1)
函数声明的参数类型可能不完整。
但是,对于数据成员声明和所有定义,类型必须完整:
struct A;
struct B {
void f(A); // declaration, fine
void g(A) {} // error
A a; // error
};
答案 2 :(得分:0)
问题是当您更改struct X中的声明时。
因此,在struct X中你告诉编译器struct有一个函数接收类型为X的东西,但是等一下,类型X在这一点上还没有完全定义!
您不能将不完整类型用作函数f的参数,但可以使用不完整类型的地址,即X *。
在网站上注意,提高你的录取率对你来说非常重要,这样你就可以得到未来问题的答案,如果我得到正确的答案,对我的自我很重要:)