Обоснование наблюдаемого поведения:
Компилятор использует конструктор преобразования в производном классе,
bar(int a)
для оценки:
a = 40;
Он принимает целое число 40
и создает объект bar
, используя конструктор преобразования, а затем назначает созданный объект bar
для a
, используя оператор неявного копирования (=
), сгенерированный компилятором. для класса bar
.
По этой причине вы видите дополнительные вызовы конструктора bar
, а перегруженный базовый класс =
никогда не вызывается. Кроме того, причина двойного освобождения заключается здесь: у вас есть несколько bar
объектов, которые продолжают указывать на динамическую память, выделенную для ptr_x
, и когда один из объектов выходит из области видимости, вызывается деструктор, который освобождает память, но оставляет указатель члена другого объекта в висячем состоянии.
Как решить эти проблемы:
Вы должны пометить конструктор преобразования явный , если вы не хотите, чтобы компилятор использовал его для неявных преобразований, подобных этой.
Вы должны следовать правилу трех для своего класса bar
.
Оговорка:
Обратите внимание, что оператор =
в базовых классах всегда скрыт неявно сгенерированным оператором =
для производного класса.