我正在使用C++ .NET 2.0

我有两种形式

第一个声明如下

#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.h中,我有
/*... snip... */
#include "SubForm.h"
#include "frmMain.h"

现在开始提问!
SubForm中的行使编译器告诉我“使用未定义的类型myNamespace::frmMain

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

最佳答案

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

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

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

public void exportRows(String^ text);

那么您可以定义:
public void SubForm::exportRows(String^ text)
{
    /*... snip ...*/
    myMain->addNewRow("myNewText");
}

在SubForm.cpp中,一切都应该出色完成。

编辑:良好的面向对象设计涉及到将接口(interface)与实现分开,而在C++中实现此目的的最佳方法是将接口(interface)保留在头文件中,并将实现代码保留在相应的源文件中。

最重要的是,头文件应仅包含声明。将它们视为类的接口(interface)。头文件仅显示您的类将实现的功能签名。另一方面,源文件包含所有定义,它们是类的实现。

关于.net - 前向申报问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/376232/

10-12 19:28