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 ++编译器要求您声明在您可以引用它之前的所有内容,因此必须先声明structY
,然后才能将其成员Y::f(X*)
声明为structX
中的朋友。但对于Y::f(X*)
要声明structX
必须首先声明!这是解决方案。请注意
Y::f(X*)
获取X
对象的地址。这很关键,因为编译器总是知道如何传递一个地址,无论传递的对象是什么,它都是固定大小的,即使它没有关于类型大小的完整信息。 “
所以我们在这里:
struct X; struct Y { ... }; struct X { ... };
我的问题是:
为什么编译器坚持认为X
不完整地声明为:struct X;
??
毕竟,正如作者所说:“编译器总是知道如何传递地址
这是一个声明告诉编译器X
是一个结构并且很快就会遵循的声明,所以为什么编译器如此坚持你输入字母:struct {{1}毕竟我本身没有使用X
?那时没有生成汇编语言代码。当它读取X
时肯定可以告诉它是一个地址(指针) ..为什么:X*
需要?
声明函数的重点是在实际之前进行类型检查 用法。所以,如果我这样做:
struct X;
并且编译器会发出嚎叫声。但是在上面,如果我不说: int foo(void); foo(30);
它有什么区别?他只是检查我的struct X;
(函数名称)的拼写吗?
为什么不反转struct Y和X的位置有效?像这样:
X
我明白了:
错误:无效使用不完整类型
struct Y; struct X { ... }; struct Y { ... };
显然,编译器对我的不完整类型规范不满意
'struct main()::Y'
(Y
)。但是缺少什么珍贵的小信息?后
所有结构struct Y;
;应告诉编译器Y
即将遵循(与执行相同)
我们在Q1中做了什么:Y
)
为什么作者将结构struct X; struct Y {}; struct X{};
称为定义?如果我做:
X
这肯定是宣言?当我实例化的时候
像这样的结构:struct X { ... };
foo;那么它是一个定义?正确的吗?
我该怎么做:
X
答案 0 :(得分:2)
为什么编译器坚持认为X不完整地声明为:struct X ??毕竟,正如作者所说:“编译器总是知道如何传递一个固定大小的地址......”
你没有:这也有效:
struct Y { void f(struct X*); };
class X {
int i;
friend void Y::f(X*);
};
您建议使用 else ?
此外,除非实际定义方法,否则在传递值时甚至不必具有完整类型:
struct Y { void f(struct X); };
// too early:
void Y::f(struct X) { /* whoops compile error */ }
class X {
int i;
friend void Y::f(X);
};
// ok here:
void Y::f(X) { /* compile success */ }
答案 1 :(得分:1)
毕竟,正如作者所说:“编译器总是知道如何传递一个固定大小的地址..”这只是一个声明告诉编译器X是一个结构并很快就会遵循的原因,为什么编译器是如此坚持你输入字母:
struct X;
毕竟我不使用X本身?当时没有生成汇编语言代码..当它读取“X *”时,它肯定会告诉它是一个地址(指针)..为什么:struct X;
需要?
作者并没有告诉你所有令人讨厌的细节。如果知道什么类型的对象X
,编译器知道如何传递指针(地址)。该语言允许一些指针,如指向word-adressable机器上的char
指针,或指向函数的指针,具有不同的大小。
因此,您必须告诉编译器X
是struct
而不是内置类型的函数或typedef。