Voici mon code:Comment mettre en œuvre constructeur de copie en toute sécurité pour la classe qui a le placement interne nouveau (avec std :: string)
struct RS_Token
{
char id;
char cleanup;
unsigned char array[sizeof (std::string) > sizeof (double) ? sizeof (std::string) : sizeof (double)];
RS_Token(int a) :
id(a),
cleanup(0)
{
}
RS_Token(int a, const char* pstr) : // identifier or text
id(a),
cleanup(1)
{
new (array) std::basic_string<unsigned char>((unsigned char*)pstr);
}
RS_Token(int a, int b) : // integer
id(a),
cleanup(0)
{
new (array) int(b);
}
RS_Token(int a, double b) : // float (double)
id(a),
cleanup(0)
{
new (array) double(b);
}
~RS_Token()
{
if (cleanup)
{
std::basic_string<unsigned char>* p = reinterpret_cast<std::basic_string<unsigned char>*>(array);
p->~basic_string();
}
}
};
Toutes les suggestions sur la façon d'ajouter un constructeur de copie qui gère correctement le cas où un std :: string a été attribué en interne, serait apprécié.
Ce qui est mal à faire à part 'std :: string' et les variables' double'? Le code que vous avez aura [sérieux problèmes d'alignement] (http://www.gotw.ca/gotw/028.htm) entre autres choses. Et si vous en faites des variables membres distinctes, le constructeur de copie généré par le compilateur fera le bon choix pour vous. –
Placement-nouveau prend généralement un argument 'void *', donc vous pouvez vous épargner ces moulages fastidieux. –
Probablement 'boost :: variant' prendrait soin de ces choses. –
visitor