Почему 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_ptrs конструктор копирования, который должен просто увеличивать счетчик ссылок. Заранее спасибо.

Обновлено с минимальной версией. Интересно отметить, что 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.

0 ответов

Другие вопросы по тегам