Что может сломать, так это то, что экземпляры не-POD класса могут иметь указатели vtable для реализации виртуальной диспетчеризации, если у них есть какие-либо виртуальные функции, включая виртуальный dtor.Указатель vtbl обычно будет первым членом не POD-класса.
(Технически виртуальная диспетчеризация не должна быть реализована таким образом; практически так и есть. Поэтому стандарт должен быть настолько строг в отношении того, что квалифицируется как тип POD.)
I 'Я, честно говоря, не уверен, почему просто наличие ctor («8.5.1 (1):« Агрегат - это массив или класс (раздел 9) без объявленных пользователем конструкторов (12.1) »), что не признает POD. Но,это так.
В конкретном случае, который у вас здесь есть, разумеется, нет необходимости переинтерпретировать приведение. Вместо этого просто добавьте оператор преобразования в базовый класс:
class complex_base // a POD-class (I believe)
{
public:
double m_data[2];
operator double*() {
return m_data;
}
};
complex_base b; // create a complex_base
double* p = b;
complex_base не является double *, компилятор C ++ будет применять один (и только один) пользовательский оператор преобразования, чтобы назначить b для p. Это означает, что p = b
вызывает оператор преобразования, давая p = b.operator double*()
(иобратите внимание, что это на самом деле допустимый синтаксис - вы можете напрямую вызывать операторы преобразования, а не то, что вы должны), который, конечно, делает все, что он делает, в этом случае возвращает m_data.
Обратите внимание, что это яs сомнительно, так как теперь у нас есть прямой доступ к внутренностям b.На практике мы можем вернуть const double *, или копию, или умный «указатель» при копировании при записи, или ....
Конечно, в этом случае m_data в любом случае общедоступна, поэтомумы ничуть не хуже, чем если бы мы только что написали:
double* p = b.m_data;
На самом деле мы немного лучше, потому что клиентам complex_base не нужно знать как , чтобы преобразовать егов два раза.