C++ 中的友元声明

问题描述 投票:0回答:3

Bruce ekel 的《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);  

作为结构体Y中的声明,它没有显示错误。 请解释一下为什么?

c++ declaration friend
3个回答
1
投票

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

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

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

1
投票

按值传递不完整对象

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


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.