为什么这个C ++程序提供了编译时错误,尽管提供了前向声明?

时间:2011-11-01 14:01:35

标签: visual-c++

代码:

#include<iostream>

using namespace std;

class MyClassOne;

class MyClassTwo
{
    int myInteger;
    float myFloat;

public:
    void SetData(int myIntegerParameter, float myFloatParameter)
    {
        myInteger = myIntegerParameter;
        myFloat = myFloatParameter;
    }
    void Show(MyClassOne myObjectParameter)
    {
        cout<<"MyClassOne..."<<"\n";
        cout<<myObjectParameter.myInteger<<"\n";
        cout<<myObjectParameter.myFloat<<"\n";

        cout<<"MyClassTwo..."<<"\n";
        cout<<myInteger<<"\n";
        cout<<myFloat<<"\n";
    }
};

class MyClassOne
{
    int myInteger;
    float myFloat;

public:
    void SetData(int myIntegerParameter, float myFloatParameter)
    {
        myInteger = myIntegerParameter;
        myFloat = myFloatParameter;
    }
    friend void MyClassTwo :: Show(MyClassOne);
};

int main()
{
    MyClassOne myObjectOne;
    myObjectOne.SetData(10, 10.5);

    MyClassTwo myObjectTwo;
    myObjectTwo.SetData(20, 20.5);

    myObjectTwo.Show(myObjectOne);

    return 0;
}

错误消息:

1>friend_function.cpp(22) : error C2027: use of undefined type 'MyClassOne'
1>friend_function.cpp(6) : see declaration of 'MyClassOne'
1>friend_function.cpp(22) : error C2228: left of '.myInteger' must have 

class/struct/union
1>friend_function.cpp(23) : error C2027: use of undefined type 'MyClassOne'
1>friend_function.cpp(6) : see declaration of 'MyClassOne'
1>friend_function.cpp(23) : error C2228: left of '.myFloat' must have 

class/struct/union
1>Generating Code...
1>Build log was saved at "file://Debug\BuildLog.htm"
1>Problem_05___Friend_Function - 4 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

3 个答案:

答案 0 :(得分:3)

MyClassTwo::Show需要完整定义MyClassOne

Show方法的正文移到MyClassOne的定义之后,它会起作用。

答案 1 :(得分:1)

因为除了提供指向对象的指针之外,你不能使用前向声明。

您可以执行以下操作:

//MyClassTwo.h
//declaration in header
void Show(MyClassOne* myObjectParameter);

并将实现移动到cpp文件:

//MyClassTwo.cpp
void MyClassTwo::Show(MyClassOne* myObjectParameter);
{
    cout<<"MyClassOne..."<<"\n";
    cout<<myObjectParameter->myInteger<<"\n";
    cout<<myObjectParameter->myFloat<<"\n";

    cout<<"MyClassTwo..."<<"\n";
    cout<<myInteger<<"\n";
    cout<<myFloat<<"\n";
}

前向声明允许您使用指针,因为它们的大小相同。使用实际实例意味着您必须知道对象的大小,因为它将被推送到方法的参数堆栈中。但你不知道它的大小,因为它还没有遇到声明。声明好友时,更改声明顺序会出错。

实施和声明的分离是可行的方法。

答案 2 :(得分:0)

要访问类的成员,您需要其定义,而不仅仅是其声明。

具体而言,如果您希望MyClassOne访问MyClassTwo的成员,则需要在MyClassTwo定义之上设置MyClassOne定义。

此外,将MyClassOne作为const的引用传递给MyClassTwo::Show()成员函数是个好主意。因此,您应该将其重新定义为:

void Show(const MyClassOne &myObjectParameter)