Умные указатели (shared_ptr) - PullRequest
3 голосов
/ 30 марта 2020

Я пытаюсь научиться пользоваться умными указателями. Я долгое время использую обычные указатели и думаю, что мне нужно улучшить свои навыки.

Я провожу некоторые исследования, понимаю некоторые аспекты умных указателей, но пытаюсь реализовать их в ясном проекте, чтобы понять, как умные указатели работают. Я пытаюсь:

#include <iostream>
#include <array>
#include <memory>

class Entity
{
public:
    Entity()
    {
        std::cout << "Entity called!" << std::endl;
    }
    ~Entity()
    {
        std::cout << "Entity destroyed!" << std::endl;
    }
    void print() { std::cout << "Message!"; }
};

int main()
{
    std::shared_ptr<int>f1(new int[100]);

    f1.get()[1] = 1;
    std::cout << f1.get()[1];
}

все хорошо, сообщение, это печать. Но когда я пытаюсь:

#include <iostream>
#include <array>
#include <memory>

class Entity
{
public:
    Entity()
    {
        std::cout << "Entity called!" << std::endl;
    }
    ~Entity()
    {
        std::cout << "Entity destroyed!" << std::endl;
    }
    void print() { std::cout << "Message!"; };
};

int main()
{
    std::shared_ptr<Entity>f1(new Entity[100]);

    f1.get()[1].print();
}

я получаю эту ошибку: [img] https://i.imgur.com/U30gTgC.png [/ img]

следующий:

int main()
{
    std::shared_ptr<Entity>f1(new Entity[100]);

    (f1.get() + 1)->print();
}

та же ошибка.

Я пытаюсь использовать std :: make_shared:

#include <iostream>
#include <array>
#include <memory>

class Entity
{
public:
    Entity()
    {
        std::cout << "Entity called!" << std::endl;
    }
    ~Entity()
    {
        std::cout << "Entity destroyed!" << std::endl;
    }
    void print() { std::cout << "Message!"; };
};

int main()
{
    std::shared_ptr<Entity>f1 = std::make_shared<Entity>();

    f1->print();
}

все в порядке.

Я пытаюсь выделить память продолжения с помощью int:

#include <iostream>
#include <array>
#include <memory>

class Entity
{
public:
    Entity()
    {
        std::cout << "Entity called!" << std::endl;
    }
    ~Entity()
    {
        std::cout << "Entity destroyed!" << std::endl;
    }
    void print() { std::cout << "Message!"; };
};

int main()
{
    std::shared_ptr<int>f1 = std::make_shared<int>(100);

    f1.get()[1] = 10;
    std::cout << f1.get()[1];
}

сообщение печатается, вывод: 10, но ошибка: https://i.imgur.com/UPu7VZo.png

я пытаюсь по-другому:

int main()
{
    std::shared_ptr<int>f1 = std::make_shared<int>(100);

    *(f1.get() +1) = 10;
    std::cout << *(f1.get() + 1);
}

та же ошибка.

std::shared_ptr<Entity[]>f1 = std::make_shared<Entity[]>(new Entity[100]);

у меня ошибка ...

Что я пытаюсь сделать примерно так:

int main()
{
    Entity* f1 = new Entity[100];

    f1[0].print();
    f1[1].print();
    f1[2].print();

}

, но я хочу использовать умные указатели.

для int Я хочу сделать какое-то назначенное значение, например:

int main()
{
    int* f1 = new int[100];

    f1[0] = 14;
    f1[1] = 20;
    f1[2] = 5;
}

Как я могу сделать что-то подобное с помощью умных указателей. Я хочу использовать: std :: make_shared (new Entity [100]) или что-то вроде этого.

Я могу попробовать с библиотекой, такой как вектор или массив, но я не хочу использовать эту библиотеку на данный момент. Я хочу, чтобы мой код был чистым на данный момент. После того, как я пойму 100% умные указатели, я буду использовать массив и векторную библиотеку

Ответы [ 2 ]

5 голосов
/ 30 марта 2020

Не

std::shared_ptr<Entity[]> f1 = std::make_shared<Entity[]>(new Entity[100]);

, но

std::shared_ptr<Entity[]> f1 = std::make_shared<Entity[]>(100);

или даже проще

auto f1 = std::make_shared<Entity[]>(100);

Когда вы используете make_shared, вы не должны использовать new. Одна из точек make_shared заключается в более эффективном распределении памяти, чем если бы вы использовали new.

Примечание: для массива make_shared требуется C ++ 20.

2 голосов
/ 30 марта 2020

Пример кода, который должен работать для вас:

int main() {
    std::shared_ptr<Entity[]>f1(new Entity[100]);

    f1.get()[1].print();
}

Что касается make_shared, вам не повезло - текущий CPP стандарт 17, кажется, не поддерживает it (см. https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) Однако make_shared используется только для устранения условия гонки в распределении и может быть реализован вручную или просто пропущен. Я призываю прочитать больше об этом.

...