Несобственный указатель как член класса в современном c ++ - PullRequest
2 голосов
/ 11 февраля 2020

Я исследовал умные указатели и когда они должны использоваться против сырых указателей. Я забрал то, что объекты, которые СОБСТВЕННЫ для указателя, должны создавать этот указатель как интеллектуальный указатель (unique_ptr / shared_ptr).

Затем при передаче этого указателя различным функциям / классам, которые не требуют его владения, передайте необработанный указатель (полученный из умного указателя через .get()) с предупреждением, что функция / класс, который необработанный указатель отправляется НИКОГДА не изживет область действия функции / класса, которой он принадлежит.

Правильно ли это понимание? Кажется, это имеет смысл для меня, но когда я начал реализовывать конкретную подпрограмму c, моя уверенность уменьшилась.

Следующий код лучше объяснит, где находится мое зависание. У меня есть элемент-член от unique_ptr s до Mesh объектов в Scene. Затем я передаю необработанный указатель созданного unique_ptr для создания экземпляра объекта Actor и, наконец, перемещаю unique_ptr в вектор scene->meshes.

Является ли факт, что Actor имеет Mesh* как член, не считающийся дурной практикой, если сфера действия любого Actor никогда не переживет область действия элемента scene->meshes?

#include <iostream>
#include <vector>
#include <memory>

class Mesh
{
public:
    int vec = 1;
    int ind = 2;
};

class Actor
{
private:
    Mesh * mesh;
public:
    Actor(Mesh* m) {
        this->mesh = m;
    }
};

class Scene
{
public:
    // meshes will always outlive all instantiated actors
    std::vector<std::unique_ptr<Mesh>> meshes;
    std::vector<Actor> actors;
};


int main()
{
    auto scene = std::make_unique<Scene>();

    auto m1 = std::make_unique<Mesh>();
    auto a1 = Actor(m1.get());
    scene->meshes.push_back(std::move(m1));

    auto m2 = std::make_unique<Mesh>();
    auto a2 = Actor(m2.get());
    scene->meshes.push_back(std::move(m2));

    std::cout << scene->meshes.size();

    std::cin.get();
    return 0;
}

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Является ли тот факт, что Актер имеет Me sh* в качестве члена, не считается плохой практикой, пока ...

Это кодовый запах, конечно. Класс легко использовать неправильно. Необходимо тщательно задокументировать, что конструктор хранит указатель на время существования актера, чтобы предупредить пользователя о необходимости поддерживать время жизни указанного мной sh.

В таком случае общее владение будет безопаснее. Но это не всегда лучший выбор, если производительность существенно.

0 голосов
/ 11 февраля 2020

Это правильно, но очень некрасиво.

Можно рассмотреть третий класс, реализующий отношение, и любые действия, действующие на это отношение.

A Контроллер сорта .

...