How to implement safe copy constructor for class that has internal placement new (with std::string)
Here's my code:
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_stri开发者_Go百科ng<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();
}
}
};
Any suggestions on how to add a copy constructor that properly handles the case where a std::string has been allocated internally, would be appreciated.
I'm not sure that what you're doing is at all a good design, but to answer your question about placement-new: You provide the constructor arguments just like in any other new
expression:
Construct new string:
typedef std::basic_string<unsigned char> ustring;
RS_Token(const char* pstr)
{
void * p = static_cast<void*>(array);
new (p) ustring(pstr, pstr + std::strlen(pstr));
}
Copy-construct:
RS_Token(const RS_Token & other)
{
void * p = static_cast<void*>(array);
new (p) ustring(*reinterpret_cast<const ustring *>(other.array));
}
Assign:
RS_Token & operator=(const RS_Token & other)
{
ustring & s = *reinterpret_cast<ustring *>(array);
s = *reinterpret_cast<const ustring *>(other.array);
return this;
}
精彩评论