c++编程思想里面的错误(可能c++标准变了,所以以前的东西没有更新)

第一卷  第五章 5.3友元

下面的代码是《c++编程思想》里面的代码,

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

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

void X::initialize(){
  i=0;  
}

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

  

struct X;是一个不完全类型说明,(不完整类型是这样一种类型,它缺乏足够的信息例如长度去描述一个完整的对象。

《c++编程思想》里面的原话:struct Y有一个成员函数f(),它将修改X类型的对象。这里有一个难题,因为c++编译器要求在引用任一变量之前必须先声明,所以struct Y必须在它的的成员Y::f(X*)被声明为struct X的一个友元之前声明,但要声明Y::f(X*),又必须先声明Struct X.

  解决的办法:注意到Y::f(X*)引用了一个X对象的地址,这一点很关键,因为编译器知道如何传递一个地址,这一地址具有固定的大小,而不管被传递的是什么对象,即使它还没有完全知道对象类型大小。然而,如果试图传递整个对象,编译器就必须知道X的全部定义以确定它的大小以及如何传递,这就使得程序员无法去声明一个类似于Y::g(x)的函数。

上面的斜体字是书中的原话,红色字体是我想存在疑问的地方,于是写如下代码

#include<iostream>
using namespace std;
struct X;
struct Y{
   void f(X*); 
   void g(X);
};

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

void X::initialize(){
  i=0;  
}
void Y::f(X* x){
   x->i=10;
}

void Y::g(X x){
    cout<<x.i<<endl;
}
int main(){
  X x;
  x.initialize();
  Y y;
  y.f(&x);    
  y.g(x);
    
}

  上面的代码,在Struct Y这个结构体中加入了一个成员函数,g(X),传递的参数就是struct X的整个对象,并非指针,我们也只是在Y::g(X)之前做了一个不完全类型说明,编译仍然是可以通过,并可以运行的,上面的代码和红色字体所说的相违背

原文地址:https://www.cnblogs.com/cplinux/p/5543988.html