【问题标题】:friend class with forward class declaration does not compile具有前向类声明的朋友类无法编译
【发布时间】:2013-05-06 12:06:50
【问题描述】:

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

xxx 类有一个使用friend 的类yyy 对象。自上课yyyxxx 类之后定义我已经使用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

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

【问题讨论】:

    标签: c++ friend friend-class


    【解决方案1】:

    您正在这里实例化一个不完整类型的对象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;,编译器必须知道 compile-time 它应该为y2 保留多少内存。由于yyy 类型不完整(仅在实例化点前向声明),因此编译器丢失并报告错误。

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

    【讨论】:

    • 它不起作用,因为 y.Show() 在您调用它之前尚未声明。 Haroogan 的解决方案将解决这个问题。
    • 当然,如果该实现保留在标头中,您可能会遇到链接器错误;您应该将其放入 .cpp 文件中或将其标记为内联。
    • 感谢 Harogan 的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多