1

我正在使用 C++ .NET 2.0

我有 2 个表格

第一个声明如下

#include "stdafx.h"
    namespace myNamespace{

      public ref class frmMain : public System::Windows::Forms::Form {
      /*... snip ...*/
      public void addNewRow(String^ text){ /*... snip... */  }
      public void launchSubForm() { SubForm^ sf = gcnew SubForm(this); sf->Show(); }

      };
    }

第二个是这样的

#include stdafx.h
    namespace myNamespace{
      ref class frmMain;
      public ref class SubForm : public System::Windows::Forms::Form {
      frmMain^ myMain;
      SubForm ( frmMain^ pMain){
        myMain = pMain;
      }
      /*... snip ...*/
      public void exportRows(String^ text){ /*... snip... */  }
        myMain->addNewRow("myNewText");   <--- This line causes compile error
      };
    }

在 stdafx.hi 中有

/*... snip... */
#include "SubForm.h"
#include "frmMain.h"

现在问题来了!SubForm 中的行导致编译器告诉我“使用未定义类型 myNamespace::frmMain

我真的不知道为什么“ref class frmMain”不能解决这个问题

4

2 回答 2

3

这是因为这两个头文件都包含“stdafx.h”,而stdafx.h在“frmMain.h”之前包含“SubForm.h ”。

因此,在“SubForm.h”中,编译器希望在定义 frmMain 之前定义 SubForm,从而导致错误。

解决此问题的正确方法是将类的所有代码保留在适当的源文件中,而不是在头文件中。如果您的头文件只是声明:

public void exportRows(String^ text);

那么你可以定义:

public void SubForm::exportRows(String^ text)
{
    /*... snip ...*/
    myMain->addNewRow("myNewText");
}

在 SubForm.cpp 中,一切都应该很顺利。


编辑:良好的面向对象设计涉及将接口与实现分离,而在 C++ 中实现这一点的最佳方法是将接口保存在头文件中,并将实现代码保存在相应的源文件中。

底线是你的头文件应该只包含声明。将这些视为您的类的接口。头文件仅显示您的类将实现的函数签名。另一方面,源文件包含所有定义,它们是您的类的实现。

于 2008-12-17T22:31:06.607 回答
0

在 C++ 中,如果您没有在指针上调用方法或对该类的引用,则只能前向声明一个类。任何时候尝试调用类指针或引用的方法时,都需要有可用的类定义。

删除不完整的类型是合法的,但非常危险。

请使用与 C++ 不同的标签,因为这不是 C++。

于 2008-12-17T22:53:13.067 回答