这是一个基本程序,用于了解如何在C++中使用friend class
xxx类具有一个使用yyyfriend类对象。由于类yyy是在类xxx之后定义的,我已使用forward声明了类yyy宣言。

#include<iostream>
using std::cout;
using std::endl;

class yyy; //Forward Declaration of class yyy

class xxx{
private:
  int a;

public:
  xxx(){a=20;yyy y2;y2.show();}       //Error//
  void show(){cout<<"a="<<a<<endl;}
  friend class yyy; //Making class yyy as freind of class xxx
};
class yyy{
private:
  int b;

public:
  yyy(){b=10;}
  void show(){cout<<"b="<<b<<endl;}
};

int main(int argc, char *argv[])
{
  xxx x1; //creating xxx object and calling constructor
  x1.show();
  return 0;
}

当我编译程序时,出现此错误:



我提到这个连结
recursive friend classes
有人回答过
https://stackoverflow.com/a/6158833/2168706

我正在采用这种方法,但仍然无法解决
问题。如果有的话,请提供解决方案,并让我知道
如果我在代码中的任何时候都错了。

最佳答案

您正在此处实例化类型不完整y2的对象yyy:

{ a = 20; yyy y2; y2.show(); }

将构造函数的实现移到yyy类的定义下方:
class yyy;

class xxx {
  private:
    int a;

  public:
    xxx();

    void show() { cout << "a=" << a << endl; }

    friend class yyy;
};

class yyy {
  private:
    int b;

  public:
    yyy() { b = 10; }

    void show() { cout << "b=" << b << endl; }
};

xxx::xxx() { a = 20; yyy y2; y2.show(); } // No error

结果,此时已经定义了yyy,您可以实例化y2

为了给您一个逻辑上的解释,为什么您的变体不起作用:当您使用yyy y2;这样的自动存储持续时间(在堆栈上)实例化对象时,编译器必须在编译时知道,它应该为它保留多少内存y2。由于yyy类型不完整(仅在实例化时才向前声明),编译器将丢失并报告错误。

注意:最佳实践当然是通过将定义移到头文件(.hpp)和将实现移到源文件(.cpp)来分离类及其实现的定义。不要忘记正确包含标题。我不想在这里给您一个示例,因为它是非常基本的内容,任何C++书籍或教程都应涵盖。

关于c++ - 具有前向类声明的 friend 类无法编译,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16398416/

10-10 18:12