Je travaille sur l'implémentation d'une carte de pointeurs de variables membres associés à une clé de chaîne. Toutes les variables vont d'une classe de base "BaseA" Lors de l'accès aux variables de la carte, il est seulement nécessaire d'utiliser les méthodes de classe de base (getDesc()), il n'est donc pas nécessaire de récupérer le type original.std :: map des variables de variables membres polymorphes
Ce code compile et s'exécute sous GNU g ++ 6.2.1, mais d'après ce que j'ai lu, l'utilisation de reinterpret_cast n'est pas portable et peut ne pas fonctionner avec d'autres compilateurs. Est-ce correct? Ou ce code est-il conforme aux normes C++? Existe-t-il un autre moyen de le faire sans utiliser reinterpret_cast? Une exigence est que "Vars" doit être copiable avec les implémentations de copie-contructeur et de copie-affectation par défaut.
Exemple de code:
#include <iostream>
#include <sstream>
#include <map>
#include <typeinfo>
using namespace std;
struct BaseA
{
virtual string getDesc() = 0;
};
struct A1 : BaseA
{
string getDesc() override { return "This is A1"; }
};
struct A2 : BaseA
{
string getDesc() override { return "This is A2"; }
};
struct Vars
{
A1 a1;
A2 a2;
map< string, BaseA Vars::* > vars;
Vars()
{
vars["A1_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a1);
vars["A2_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a2);
}
BaseA& get(const string& key)
{
auto it = vars.find(key);
if (it != vars.end())
{
return this->*(it->second);
}
throw std::out_of_range("Invalid variable key:[" + key + "]");
}
};
int main()
{
Vars v;
cout << "a1 description :" << v.get("A1_KEY").getDesc() << endl;
cout << "a2 description :" << v.get("A2_KEY").getDesc() << endl;
return 0;
}
Je ne recommande pas d'utiliser 'std :: string' comme clé pour' std :: map'. Si possible (comme dans la plupart des cas), utilisez un 'enum'. – DeiDei
Merci DeiDei. J'utilise enum quand c'est possible, mais dans ce cas, l'idée est que la clé est entrée par l'utilisateur comme une ligne de commande, donc je comprends qu'une chaîne s'adapte mieux – SNJ