Classe gérée avec un non-membre géré
Je suis à l'aide de cette classe:
public ref class x: public System::Windows::Forms::Form
{
private: gcroot<std::string> name;
}
et j'obtiens l'erreur suivante:
IntelliSense: a member of a managed class cannot be of a non-managed class type
Je sais que je peux utiliser char*
, mais si j'utilise beaucoup de char*
je vais devoir le faire manuellement la delete[]
ou certains tas de problèmes d'endommagement seront à la hausse
Je suis coincé sur cette question depuis deux jours maintenant
note: j'ai utiliser le c++, et utiliser l'INTERFACE utilisateur en c++
OriginalL'auteur HalaKuwatly | 2013-11-24
Vous devez vous connecter pour publier un commentaire.
C'est une mauvaise utilisation de gcroot<>, vous n'avez besoin que si vous gardez une référence à un géré objet d'une exploitation non maîtrisée de classe.
Dans ce cas, vous avez seulement besoin de le déclarer
string*
. Un pointeur, vous ne pouvez pas stocker une chaîne de caractères de l'objet à l'intérieur de votre géré classe, le compilateur est convaincu que vous allez tirer votre jambe large. Vous obtiendrez exactement le même message d'erreur tu as maintenant.Vraiment Mauvaises Choses peuvent se produire lorsque le garbage collector compacte le tas gc et se déplace de l'objet de Formulaire. Qui invalide toute externe non géré pointeur vers la chaîne de l'objet sans le garbage collector être en mesure de mettre à jour le pointeur. Tel un pointeur peut par exemple être généré lorsque vous passez une référence à la chaîne de caractères pour le code non managé et le GC se produit alors que le code non managé est en cours d'exécution. Le pointeur n'est plus valide et le code non managé échoue lors de la lecture d'ordures ou de corrompt le tas GC. Surtout le dernier incident est extrêmement difficile à diagnostiquer. Juste appeler l'un des std::string membre des méthodes suffit de l'invoquer ce mode de défaillance, qui génère le ce pointeur.
Il est très rare qu'on en fait besoin un std::string dans un objet géré, vous devez toujours choisir
String^
premier. Et de générer de la std::string uniquement lorsque cela est nécessaire, en général, lorsque vous appelez en code natif. Ne jamais envisager de le faire à votre façon, si la création de la std::string à la volée est extrêmement coûteux. Si vous ne créez ensuite les std::string objet dans le constructeur. Et la détruire à nouveau dans les deux, le destructeur et le finalizer. Ce qui est assez délicat à obtenir le droit pour le Formulaire de classe depuis qu'il a déjà un destructeur et finalizer, fortement envisager de créer un peu de la classe helper que les magasins de la chaîne.OriginalL'auteur Hans Passant
gcroot
est utilisé pour un autre but: garder CLR membre de la classe dans une classe native. Vous avez besoin de garder natif de membre de classe en classe CLR. Ce n'est pas directement en tant que bien, mais vous pouvez garder pointeur natif de la classe en tant que membre:Initialiser
name
ànew string("...");
dans le constructeur de la classe ou dans un autre endroit où cela est nécessaire, et de l'utiliser. Pour empêcher la fuite de mémoire, la libérationname
dans la classe finaliseur et destructeur.Notes:
Éviter d'utiliser des types mélangés si ce n'est pas absolument nécessaire. Par exemple, dans ce cas, vous pouvez utiliser pure CLR
String^
au lieu de nativestd::string
.À écrire le code C++ avec une interface graphique, il est beaucoup mieux d'utiliser certains indigènes framework d'INTERFACE: API Win32, MFC, Qt, etc. À l'aide de Formulaires Windows GUI en C++/CLI est très difficile - vous besoin de connaître le bien et C++.NET. En tout cas, C++/CLI application Windows Forms type est abandonné dans les plus récentes versions de Visual Studio. Revoir votre approche.
Oui.
delete name; name = NULL;
OriginalL'auteur Alex F
Si vous incorporez un non géré la classe dans une classe managée vous aurez besoin de 'pin' parce que le garbage collector peut effectivement "compact" au cours de l'exécution de la gestion de classe, essentiellement à déplacer l'adresse réelle de la non géré classe dans le tas qui peuvent causer d'énormes problèmes. Il faut donc utiliser la
__pin
mot clé lors de l'initialisation de votre géré classe qui contient de la non géré références.OriginalL'auteur