2013-05-06 65 views
2

这是一个基本程序,用于了解如何在C++中使用friend class转发类声明的朋友类不编译

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; 
} 

当我编译的程序中,我得到这个错误:

error: aggregate ‘yyy y2’ has incomplete type and cannot be defined

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

我下面这个方法,但我仍然无法解决 问题。请提供一个解决方案,如果有任何问题,请告诉我 如果我在代码中的任何一点都是错误的。

回答

6

Your're实例化不完全型yyy这里的目的y2

{ 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++书或教程中。

+0

它不起作用,因为y.Show()在您调用它之前尚未声明。 Haroogan的解决方案将解决这个问题。 – 2013-05-06 12:11:17

+1

当然,如果该实现保留在标题中,则可能会导致链接器错误;你应该把它放在一个.cpp文件中或者将它标记为内联。 – 2013-05-06 12:11:58

+0

感谢Harogan的回复。 – 2013-05-06 13:26:28