problema dichiarazione anticipata
-
22-08-2019 - |
Domanda
sto usando C ++ .NET 2.0
Ho 2 forme
il primo viene dichiarata come segue
#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(); }
};
}
la seconda va in questo modo
#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
};
}
in stdafx.h devo
/*... snip... */
#include "SubForm.h"
#include "frmMain.h"
Ora alla domanda! La linea in SubForm fa sì che il compilatore di dirmi "l'uso di tipo non definito MyNamespace :: frmMain
ho davvero alcun indizio circa il motivo per cui la "classe frmMain ref" doesnt risolvere questo problema
Soluzione
Questo perché sia di questi file di intestazione includono "stdafx.h", e stdafx.h comprende "SubForm.h" prima "frmMain.h".
Così, in "SubForm.h", il compilatore vuole definire SubForm prima frmMain è stato definito, che conduce all'errore.
Il modo corretto per risolvere questo problema è quello di mantenere tutto il codice per le classi nel file sorgente appropriata, e non nell'intestazione. Se il file di intestazione dichiara semplicemente:
public void exportRows(String^ text);
allora si può definire:
public void SubForm::exportRows(String^ text)
{
/*... snip ...*/
myMain->addNewRow("myNewText");
}
in SubForm.cpp, e tutto dovrebbe funzionare splendidamente.
modifica:. Buona Object-Oriented Design comporta la separazione di interfaccia dall'implementazione, e il modo migliore per questo in C ++ è quello di mantenere interfacce in file header e codice di implementazione nei file di origine corrispondenti
La linea di fondo è che i file di intestazione dovrebbe contenere solo dichiarazioni . Pensate a questi come l'interfaccia per le classi. Il file di intestazione mostra solo le firme delle funzioni che la classe realizzerà. I file di origine, d'altra parte, contengono tutte le Definizioni , che sono l'implementazione delle classi.
Altri suggerimenti
In C ++ è possibile solo in avanti dichiarare una classe se non si chiama un metodo su un puntatore o riferimento a tale classe. Ogni volta che si tenta di chiamare un metodo su un puntatore alla classe o di riferimento, è necessario avere la definizione della classe disponibile.
L'eliminazione di un tipo incompleto è legale, ma molto pericoloso.
Si prega di utilizzare un tag diverso da C ++, in quanto questo non è il C ++.