Я думаю, что вы путаете «распределение стека / кучи» и «автоматическую переменную».
Автоматические переменные автоматически уничтожаются при выходе из контекста.
Распределение стека - это факт, что память распределяется в стеке выполнения. И переменные, расположенные в стеке, являются автоматическими переменными.
Кроме того, члены являются автоматическими переменными , деструкторы которых вызываются, когда уничтожается его владелец. В случае указателей, они уничтожены, но не базовый объект, вы должны явно вызвать delete. Чтобы убедиться, что базовый объект уничтожен, вы должны использовать умные или уникальные указатели.
Другими словами: переменные / члены, для которых нужно вызвать delete, не являются автоматическими переменными.
Наконец, член класса размещается в том же сегменте памяти его владельца.
В вашем коде:
A.m_B
- автоматическая переменная. Если A в стеке, то B и A в куче, так же как и B. B.m_i
и D.m_i являются автоматическими переменными и будут размещаться в одном и том же сегменте памяти их владельца C.m_D
является автоматической переменной, но Указанный объект типа D не является, вы должны явно вызвать delete для указателя, чтобы удалить базовый объект. Таким образом, указатель C.m_D размещается в том же сегменте памяти, но не в основном объекте. Он будет очищен новым и будет в куче. Итак:
myA2
в куче, а не в автоматическом режиме (вам нужно delete myA2
). Его член m_B2
является автоматической переменной, которая будет уничтожена при уничтожении myA2
. Кроме того, поскольку myA2
находится в куче, m_B
, как и любой член класса, находится в той же области памяти, что и куча. myC1
находится в стеке и является автоматической переменной. Указатель на m_D
тоже находится в стеке, но не объект, указанный в m_D
, который выделяется нового в кучу. myC2
находится в куче и не является автоматическим. Поэтому вы должны удалить myC2
(который удалит m_D
). Возможно, вам удастся придумать для своего типа пользователя какие-то умные действия, которые позволят ему поступать правильно в зависимости от возможностей базы данных. Сам Hibernate использует аналогичный подход со своим «родным» генератором идентификаторов, который ведет себя по-разному в зависимости от типа используемой вами базы данных. Такой подход устраняет необходимость переключать отображение во время выполнения.
Например, вы можете создать один класс стратегии для каждой базы данных. Затем в своем классе пользовательского типа определите, к какой базе данных вы подключены при первом вызове, создайте экземпляр правильной стратегии для этой базы данных, а затем делегируйте все вызовы объекту стратегии.