struct X;
struct Y {
void f(X*);
};
struct X { //definition
private:
int i;
public:
friend void Y::f(X*);
<SNIP'd>
};
“struct
Y
有一个成员函数f()
,可以修改类型的对象X
。这有点难,因为C++ 编译器要求您在引用它之前声明所有内容Y
,因此必须先声明struct,然后才能将其成员Y::f(X*)
声明为struct 中的朋友X
。但是Y::f(X*)
要声明 structX
必须先声明!这是解决方案。请注意,它
Y::f(X*)
采用X
对象的地址。这一点很关键,因为编译器总是知道如何传递一个地址,不管传递的对象是什么,这个地址都是固定大小的,即使它没有关于类型大小的完整信息。”
所以在这里我们有:
struct X; struct Y { ... }; struct X { ... };
我的问题是这样的:
为什么编译器坚持
X
不完整地声明为:struct X;
??毕竟,正如作者所说:“编译器总是知道如何传递一个固定大小的地址。” 这只是一个声明,它告诉编译器这
X
是一个结构并且很快就会跟随,那么为什么编译器如此坚持要你输入字母: structX
; 毕竟我X
本身没有使用??那时没有生成汇编语言代码。并且当它读取X*
肯定可以说它是一个地址(指针)..为什么:struct X;
需要?声明函数的重点是在实际使用之前进行类型检查。所以如果我这样做:
int foo(void); foo(30);
编译器会嚎叫。但是在上面,如果我不说:
struct X;
它有什么区别?他只是在检查我对X
(函数名)的拼写吗?为什么颠倒结构 Y 和 X 的位置不起作用?像这样:
struct Y; struct X { ... }; struct Y { ... };
我得到:错误:不完整类型的无效使用
'struct main()::Y'
显然,编译器不满意我对
Y
(struct Y;
) 的类型说明不完整。但是缺少什么宝贵的小信息?毕竟 structY
; 应该告诉编译器Y
即将跟进(与我们在 Q1 中所做的相同struct X; struct Y {}; struct X{};
:)为什么作者将 struct
X
称为定义?如果我这样做:struct X { ... };
这肯定是一个声明?当我像这样实例化结构时:X
foo; 那么这是一个定义?正确的?我该怎么做呢:
struct X { friend void Y::f(X*); void f(Y*); }; struct Y { friend void X::f(Y*); void f(X*); };