Вызовы деструкторов являются результатом b->push_back(A{});
, а не static_pointer_cast
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
struct A {
A() { cout << "c"; }
~A() { cout << "d"; }
};
int main() {
shared_ptr<void> a = make_shared<vector<A>>(3);
auto b = static_pointer_cast<vector<A>>(a);
return 0;
}
показывает cccddd
.
Причина дополнительных вызовов деструкторов заключается в том, что вектору может потребоваться увеличить его емкость на push_back
, и когда это будет сделано, ему может понадобиться переместить / скопировать существующие элементы в новое место, и в связи с этим удалить старые элементы. Таким образом, дополнительные деструкторы, которые вы видите, являются результатом этого.
В вашем случае конструкции копирования / перемещения были созданы по умолчанию. Если вы определите их вручную и добавите в них протоколирование, вы увидите, что они совпадают.
struct A {
A() { cout << "c"; }
A(const A&) { cout << "C"; };
A(A&&) { cout << "M"; };
~A() { cout << "d"; }
};
Единственный способ предотвратить это - создать вектор с достаточно большой емкостью, чтобы вместить все элементы. что вы хотите сохранить в нем.