Размещение нового для инициализации на месте объекта - PullRequest
3 голосов
/ 31 октября 2011

Недавно я столкнулся с довольно интересным подходом сериализации, который использовал прозрачность (общее неопределенное поведение среди компиляторов?) Неинициализированных переменных для «эффективной» десериализации.

Памяти выделяется и присваивается заранее определенное значение. Затем новое размещение используется для создания экземпляра структуры (например, сложной структуры данных на месте), «инициализирующей» неинициализированные переменные значением базовой памяти. (см. код ниже)

Кроме того, что я был довольно рискованным и, возможно, не очень приятным соглашением о кодировании ... Мне было просто интересно, сталкивался ли кто-нибудь с этим методом или, что более важно, - как он называется?

class SomeClass {
public:
  SomeClass() {}

  int someInt;
};

int main(...) {
  int dummy = 42;

  int *pSomeClass = new (&dummy) SomeClass();
  cout << pSomeClass->someInt << endl;
}

Это выведет число 42 ... neato!

Ответы [ 2 ]

5 голосов
/ 01 ноября 2011

Это называется "полагаться на UB" или, по словам мирян, "глупость".

2 голосов
/ 01 ноября 2011

Я видел это в eCos, RTOS, для инициализации некоторых своих объектов ядра.

Как указал Томалак, одним из недостатков является то, что виртуальные функции не допускаются.Они пытаются гарантировать, что, проверяя на равный размер sizeof(kernel object) == sizeof(variable used for initialization).

Их код, хотя и был намного сложнее, с использованием C-struct имитировал переменные-члены класса C ++ для интерфейса c вместо использования функций C для/ установить переменные в классе C ++

Хотя поведение, к которому они шли, было совершенно противоположным, они использовали значения из класса C ++, установленные в конструкторе, для заполнения памяти из placement new.

Я не советую делать это, хотя.

...