Как реализовать конструктор безопасного копирования для класса с внутренним размещением new (с помощью std :: string) - PullRequest
0 голосов
/ 12 августа 2011

Вот мой код:

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();
        }
    }
};

Буду признателен за любые предложения о том, как добавить конструктор копирования, который правильно обрабатывает случай, когда std :: string был размещен внутри,

1 Ответ

1 голос
/ 12 августа 2011

Я не уверен, что то, что вы делаете, - это вообще хороший дизайн, но чтобы ответить на ваш вопрос о новом размещении: вы предоставляете аргументы конструктора, как и в любом другом new выражении:

Построить новую строку:

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-конструкт:

RS_Token(const RS_Token & other)
{
  void * p = static_cast<void*>(array);
  new (p) ustring(*reinterpret_cast<const ustring *>(other.array));
}

Назначение:

RS_Token & operator=(const RS_Token & other)
{
  ustring & s = *reinterpret_cast<ustring *>(array);
  s = *reinterpret_cast<const ustring *>(other.array);
  return this;
}
...