2

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

xxx有一个yyy使用friend. 由于类yyy 是在类之后定义的,xxx因此我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' 类型不完整,无法定义

我提到了这个链接 递归朋友类 ,有人这样回答 https://stackoverflow.com/a/6158833/2168706

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

4

1 回答 1

6

你在这里实例化一个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++ 书籍或教程所涵盖。

于 2013-05-06T12:09:38.553 回答