Одна из проблем вашего примера в том, что он имеет неявно объявленный, тривиальный деструктор.Несмотря на название, реализация не запрещает AFAIK делать что-то в тривиальном деструкторе класса, не являющегося POD.
Так что с юридической точки зрения в какой-то странной реализации ваш класс ex_struct
может демонстрировать поведение во время выполнения, эквивалентное следующему:
struct weird_ex_struct
{
int a,b,c,d;
weird_ex_struct() : a(123), aptr(&a) { }
weird_ex_struct(const weird_ex_struct &o) :
a(o.a), b(o.b), c(o.c), d(o.d), aptr(&a) {}
weird_ex_struct &operator=(const weird_ex_struct &o) {
a = o.a; //etc
aptr = &a;
return *this;
}
~weird_ex_struct() {
if (aptr != &a) std::terminate();
}
private:
int *aptr;
}
Я говорю поведение во время выполнения, потому что weird_ex_struct
имеет нетривиальный деструктор, и это влияет на то, как его можно использовать на законных основаниях (с одной стороны, не в профсоюзах).Кроме того, я думаю, что есть стандартные способы обнаружения существования закрытых элементов данных во время компиляции.Но до тех пор, пока реализация может хранить эту информацию в секрете, если вы не сделаете что-то неопределенное (memcpy
объект, не являющийся POD), тогда можно будет преподнести сюрприз вам позже.
Ясно, если weird_ex_struct
скопированный с memcpy
, тогда, когда он будет уничтожен, произойдет что-то странное.
Нет очевидной причины для реализации, чтобы сделать это, но стандартные левые не-POD классы широко открыты для реализаций, чтобы делать странные вещи.Не уверен, что это потому, что они думали, что кто-то подумает о какой-то полезной странности, или просто потому, что не удосужились определить стандартную компоновку , как это делает C ++ 0x.
[Редактировать: Йоханнес указал, что я ошибаюсь в отношении тривиальных деструкторов - по причинам, изложенным в части стандарта, касающейся времени жизни объекта, реализация не может делать вещи в тривиальных деструкторах, которые полагаются на содержимое памяти объекта,Возможно, они могут, если деструктор вызывается явно, я не уверен.
Тем не менее, факт остается фактом: стандарт позволяет реализациям делать довольно много сумасшедших вещей с объектами, отличными от POD, и как тольковы пишете конструктор, вы открываете эту дверь.]