Thinking in c++里面的例子程序的问题

airwing 2001-08-10 11:51:45
struct X;//declaration (incomplete type spec)

struct Y
{
void f(X*); //void f(X);
};

struct X //definition
{
private:
int i;
public:
friend void Y::f(X*); // f(X);
};

void Y::f(X x) // f(X* x)
{
x->i = 1; // x.i = 1;
}

int main()
{
Y y;
X x;
y.f(&x); // y.f(x);
}

这一段程序解释了友元的用法,其中有关于交叉引用的阐述。
他提到“。如果试图传递整个对象,编译器就必须知道X的全部定义以确定它的大小以及如何传递它,这就使程序员无法声明一个类似于Y :: f(X) 的函数。”
但是我用GCC编译时,可以声明类似于Y :: f(X) 的函数,及我在注释里的写法。
这是怎么回事,是书错了吗?请高手指教!
...全文
104 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
magicblue 2001-08-13
  • 打赏
  • 举报
回复
do_do说的也许是对的,如果是那样的话《THINKING IN C++》就错了?呵呵
我现在这里没有编译器,如果以下代码能编译成功的话就说明do_do是对的,应该是的(前提是我的猜想正确):)
class C
{
public:
void function(C x){}
private:
int a;
};
airwing 2001-08-12
  • 打赏
  • 举报
回复
对不起大家,一天没来看.其实我大体的理解和大家也差不多.小飞侠看到了我贴代码时的错误.但大家还是理解我的意思的.
先加分,看还有高手发表看法没有.好像现在各个厂商的编译器都没有这个问题
magicblue 2001-08-11
  • 打赏
  • 举报
回复
struct X //definition
{
private:
int i;
public:
friend void Y::f(X*); // 参数类型为X* (传地址)
};

void Y::f(X x) // 参数类型为X (传值)怎么和声明的不一样啊?不懂
{
x->i = 1;
}

airwing 2001-08-11
  • 打赏
  • 举报
回复
没人解释吗?为什么能用,不能给个说法吗。我觉得这一点书还是说得有一定道理的,不知道X的全部定义以确定它的大小怎么能声明Y::f(X)这样的函数呢
TeddyBro 2001-08-11
  • 打赏
  • 举报
回复
我不知道我说的是否是你想知道的,我照着你的例子解释吧
struct X;//declaration (incomplete type spec)
//这个声明只是告诉编译器有一个叫X的结构,但其细节不清

struct Y
{
void f(X*); //void f(X);
//在这里X*的定义用到了上面的关于X的声明,因为这里的函数声明没有用到X的细节,所以编译没问题。
};

struct X //definition
//定义X的细节
{
private:
int i;
public:
friend void Y::f(X*); // f(X);
};

void Y::f(X x) // f(X* x)
{
x->i = 1; // x.i = 1;
//这里用到x->i,这属于X的细节,如果没有上面的X的细节定义这里是编译不过的。
}

int main()
{
Y y;
X x;
y.f(&x); // y.f(x);
}


总之,
在用到一个类的名字时,只需要那个类的声明;
在用那个类的具体操作或成员时,必须先有类的具体定义。

Last_Dodo 2001-08-11
  • 打赏
  • 举报
回复
It is because
struct Y
{
void f(X);
};

Does not need detail of X.
If it changes to:
struct Y
{
X x;
...
};
It will not compile.
TYmir 2001-08-11
  • 打赏
  • 举报
回复
编译器的不同,即便你和作者用的是同一个编译器,但是如果版本不同,那也是不行的!
magicblue 2001-08-11
  • 打赏
  • 举报
回复
你说的意思我是明白,《THINKING IN C++》是95年(好象是)的书了,过了5,6年编译器的功能肯定比当时强多了,就像MountLion说的。编译不一定得从上到下一个接一个的编译,也许编译器看到
struct Y
{
void f(X);
};
这样的代码时会暂时跳过,接着编译struct X,完了以后再跳回原来的地方呢?呵呵,不知算不算异想天开~~~~~我也没看过编译原理:)

airwing 2001-08-10
  • 打赏
  • 举报
回复
那么应该怎么解释呢?按道理来讲,书上讲的还是友一定道理的。
MountLion 2001-08-10
  • 打赏
  • 举报
回复
老式的编译器不行,从TC++就支持了
gorge_an 2001-08-10
  • 打赏
  • 举报
回复
当然可以按照你的写法,但是我不知道是不是书上写错了!

70,022

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧