Почему make_shared дважды вызывает деструктор и вообще копирует конструктор?
Я переписываю части одного из моих старых проектов. Я написал Texture
класс, который загружает файл с диска и сохраняет данные в виде массива unsigned char
(используя внешнюю библиотеку, поэтому используя vector<unsigned char>
не вариант).
В main()
Я загружаю свои текстуры и передаю их на Scene
объект. Так как текстуры могут быть большими и одна и та же текстура может быть разделена между несколькими объектами, я создаю кучу std::shared_ptr<Texture>
с, прежде чем передать их Scene
,
Изначально проблема заключалась в том, что деструктор Texture будет вызываться дважды, что заставит malloc жаловаться на освобождение указателя, не выделяемого (внешняя библиотека использует malloc, поэтому, опять же, это не в моих руках). После некоторого исследования с выводом на консоль, кажется, что текстуры копируются через конструктор копирования, а затем сразу же уничтожаются. Я думал смысл shared_ptr
должен был не копировать объекты, а увеличивать счетчик ссылок.
Вот минимальный main()
где я создаю один shared_ptr<Texture>
:
int main(int argc, char *argv[])
{
std::shared_ptr<Texture> up(std::make_shared<Texture>("textures/lakeup.png"));
return 0;
}
Вот класс Texture
:
class Texture
{
public:
Texture(const std::string&)
{
std::cout << "Texture::Texture() for " << this << std::endl;
}
Texture(const Texture& other)
{
std::cout << "Texture::Texture(const Texture&) for " << this << std::endl;
}
~Texture()
{
std::cout << "Texture::~Texture() for " << this << std::endl;
}
};
И, наконец, вот консольный вывод для этого кода (обновлен для загрузки только одной текстуры):
Texture::Texture() for 0x7fff5fbff808
Texture::Texture(const Texture&) for 0x7fff5fbff820
Texture::Texture(const Texture&) for 0x608000043228
Texture::~Texture() for 0x7fff5fbff820
Texture::~Texture() for 0x7fff5fbff808
Texture::~Texture() for 0x608000043228
Меня смущает, почему конструкторы копирования вызываются сразу после make_shared
и почему бы нет shared_ptr
s конструктор копирования, который должен просто увеличивать счетчик ссылок. Заранее спасибо.
Обновлено с минимальной версией. Интересно отметить, что std::make_shared<Texture>()
похоже, не работает с 0 аргументами, поэтому я оставил std::string
на данный момент. Я получаю ошибку компиляции make_shared_object.hpp
на линии 711 в функции make_shared( A1 const & a1 )
,
Еще одна вещь, которую я заметил, это замена make_shared<Texture>("")
с new Texture("")
ведет себя как ожидалось:
Texture::Texture() for 0x60800022fd20
Texture::~Texture() for 0x60800022f640
Это работает, но это не очень удовлетворительно, если я уйду, не понимая, что make_shared
на самом деле делает.
Я использую XCode 5.1.1, который, кажется, соответствует llvm/clang 5.1.