具有前向类声明的友元类不编译

时间:2013-05-06 12:06:50

标签: c++ friend friend-class

这是一个了解如何在C ++中使用friend class的基本程序。

xxx使用yyy创建了一个friend类对象。上课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;
}

当我编译程序时,我收到此错误:

  

错误:聚合'yyy y2'类型不完整且无法定义

我提到了这个链接 recursive friend classes 有人像这样回答 https://stackoverflow.com/a/6158833/2168706

我正在遵循这种方法,但我仍然无法解决问题 问题。如果存在,请提供解决方案,请告诉我 如果我在代码中的任何一点都错了。

1 个答案:

答案 0 :(得分:6)

您要在此处实例化一个不完整类型y2的对象yyy

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

将构造函数的实现移到yyy class:

的定义之下
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)和实现到源文件({{1)来分离类的定义及其实现。 }})。不要忘记正确包含标题。我不想在这里给你一个例子,因为它是非常基本的东西,应该被任何C ++书籍或教程所涵盖。