MFC et STL
14 réponses
bien Sûr. Pourquoi pas?
j'utilise MFC comme couche de présentation, même si les structures et les classes dans le back-end use STL.
utilisez STL quand vous le pouvez, utilisez MFC quand il n'y a pas d'alternative
je les mélange tout le temps. Le seul PITA mineur était la sérialisation - les conteneurs MFC (CArray
,CList
,CStringArray
, etc.) support CArchive
la sérialisation, mais lors de l'utilisation de conteneurs STL vous devez faire tourner votre propre code. À la fin, je suis passé à l'utilisation boost::serialization
et jeté le MFC CArchive
trucs.
Oui, j'ai mélangé avant sans problèmes. Cependant, après avoir utilisé le CFM pendant plus d'une décennie, je n'envisagerais jamais de l'utiliser pour un nouveau projet.
j'utilise MFC pour tous mes projets C++, car aucun de mes projets n'est une console. MFC est une solution élégante pour les développeurs Windows c++. Je déteste QT, et je n'utiliserai pas WX sur Windows. Je ne me soucie pas de la portabilité, puisque mes applications ne sont que pour Windows. I love MFC / ATL's CString
la classe std::string est très brut, n'a pas toute la "Chaîne" des entités. std::string
n'est rien de plus que vector<char>
.
pour tous les algorithmes de stockage de données, J'utilise STL. J'utilise aussi le modèle de la PPL du Cdrm. classes, qui sont très semblables à STL.
Pour les collections dans la couche de données. Je ne dispose d'aucune donnée à l'appui de cette affirmation, mais je soupçonne que les collections de LST modélisées sont plus performantes que leurs homologues MFC.
Oui, je ne mélangez parce que je trouve MFC trop lourd pour la normale à l'aspect naturel c++. Bien que vous pourriez avoir à écrire un certain code pour les conversions où votre code STL parle de code MFC.
C'était une très mauvaise idée avant que Visual Studio 2003 ne supporte (presque) complètement le Standard C++. Maintenant, il n'est pas une mauvaise idée du tout. Que ce soit une bonne idée dépend du contexte et de l'ensemble des compétences de votre équipe.
Oui, si les deux conditions suivantes s'appliquent:
1) le langage choisi pour le projet est C++ (qui, bien sûr, inclut le STL - le S dans le STL est pour "Standard").
2) Après une analyse minutieuse, aucune meilleure solution de rechange n'est trouvée ou considérée comme appropriée pour le soutien de L'IGI que le MFC, et mon équipe de développement va pour cela.
cela dépend de votre définition de "mélange". Si vous voulez simplement dire créer un projet qui utilise à la fois STL et MFC, Je ne vois aucun mal à cela. Ils servent un but différent.
lorsque vous mélangez STL avec d'autres en-têtes microsoft, assurez-vous de définir NOMINMAX, sinon, votre fonction std:: min sera déformée dans une erreur de syntaxe à cause de la macro min(a,b).
vous ne devez pas utiliser d'exceptions standard dans une application MFC - votre application peut être suspendue si vous la jetez dans une boîte de dialogue. Voir cette question pour les raisons suivantes: Pourquoi mon application MFC est-elle suspendue quand je lance une exception?
j'avais une structure avec beaucoup de champs de type simple (UINT, CString, COLORREF, etc.). Le projet était en train de rassembler.
puis j'ai ajouté un CArray à la structure. Ce n'était pas la compilation.
puis j'ai implémenté operator= et copy constructor pour cette structure (l'un utilisant l'autre). Il a ensuite compilé.
quelque temps après, en faisant de la maintenance sur la structure j'ai fait une expérience: changer le CArray en std:: vector et supprimer l'opérateur= et copier constructeur. Il compilait fine et la structure était bien copiée là où l'opérateur= ou le constructeur de copie étaient appelés.
l'avantage est que je pouvais décharger une partie inutile du code - sujette aux erreurs et probablement pas mise à jour quand quelqu'un a fait de la maintenance ajoutant un champ à la structure! - je vois ça comme un gros avantage.
raison:
pourquoi je n'ai pas besoin du copy-constructor et de l'opérateur = assignment maintenant?
Avant de, la struct n'avait que des champs de type simples. Donc ils étaient copiables. Étant tous copiables, rend la structure copiables. Quand j'ai ajouté le champ de CArray, celui-ci n'était pas copiable, Car Car CArray dérive de CObject, une classe qui rend explicitement ces deux fonctions privées:
class AFX_NOVTABLE CObject
{
//...
private:
CObject(const CObject& objectSrc); // no implementation
void operator=(const CObject& objectSrc); // no implementation
//...
}
et CArray, étant une classe dérivée de CObject, ne fait rien pour outrepasser ce comportement, donc CArray en héritera et se rendra invivable. Ayant ajouté un CArray avant de faire ma structure copiables, j'étais recevoir le message d'erreur:
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxtempl.h(272) : error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(554) : see declaration of 'CObject::operator ='
c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(524) : see declaration of 'CObject'
This diagnostic occurred in the compiler generated function 'CArray<TYPE,ARG_TYPE> &CArray<TYPE,ARG_TYPE>::operator =(const CArray<TYPE,ARG_TYPE> &)'
with
[
TYPE=unsigned int,
ARG_TYPE=unsigned int &
]
std::vector est copiables par sa propre définition:
// TEMPLATE CLASS vector
template<class _Ty,
class _Ax = allocator<_Ty> >
class vector
: public _Vector_val<_Ty, _Ax>
{ // varying size array of values
public:
typedef vector<_Ty, _Ax> _Myt;
Notice _Myt est un typedef de la classe vector elle-même.
//...
vector(const _Myt& _Right)
: _Mybase(_Right._Alval)
{ // construct by copying _Right
if (_Buy(_Right.size()))
_TRY_BEGIN
this->_Mylast = _Ucopy(_Right.begin(), _Right.end(),
this->_Myfirst);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
//...
vector(_Myt&& _Right)
: _Mybase(_Right._Alval)
{ // construct by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
_Myt& operator=(_Myt&& _Right)
{ // assign by moving _Right
_Assign_rv(_STD forward<_Myt>(_Right));
return (*this);
}
//...
}
ainsi, l'ajout d'un champ Membre std:: vector à une classe struct/ne vous obligera pas à implémenter des fonctions de copie à l'intérieur de celui-ci, uniquement à cause de ce nouveau champ.
je préfère éviter les TSL et de ne pas l'utiliser parce qu'il a utilisé pour être pas si standard lorsque le MFC était standard de facto pour environ une dizaine d'années. Aussi jusqu'à ce que les versions récentes de Visual C++ (et "standard" STL), MFC ont juste de meilleures performances.