Передача std :: vector из std :: shared_ptr, без обновления объектов - PullRequest
0 голосов
/ 14 октября 2018

Хорошо, возможно, я делаю это неправильно, но я нахожусь в тупике.

У меня есть вектор shared_ptr моего класса узлов, который я передаю для разных вещей, мой класс узлов имеет векторего share_ptr - соседи типа node.

У меня есть класс, который генерирует для меня сетку узлов и возвращает std::vector<std::shared_ptr<Node>> nodes и значительный std::shared_ptr<Node> significant node.Затем я передаю этот вектор в индексатор, который создает второй список, который является подмножеством первого, размером примерно в 10%, и возвращает его как std::vector<std::shared_ptr<Node>> indexedNodes.

После того, как они созданы, я передаю их вдругой объект, который хранит их для дальнейшего использования.Затем класс-модификатор получает единственный случайный узел из indexedNodes и использует его для обхода соседей узла, изменяющих значение высоты.

Позже, когда я собираюсь экспортировать их, значения отображаются как 0/initialized.

Кое-что, чтобы заметить, я передаю данные в функции и возвращаю только с std::vector<std::shared_ptr<Node>>, который, как я понял, является моей проблемой, я просто не уверен, как правильно передать контейнер моего shared_ptr так, чтобыЯ не делаю копии.

Если потребуется дополнительная информация, дайте мне знать.Я ищу пример или ссылку, которую я могу понять.

Извините за код, это не beautful, и у меня есть его с использованием динамически загружаемых библиотек.

Функция, где работасделано:

void cruthu::Cruthu::Run() {
    std::shared_ptr<cruthu::ITeraGen> teraGen(this->mSettings.TeraGen.Factory->DLGetInstance());
    std::vector<std::shared_ptr<cruthu::Node>> nodes(teraGen->Create());
    std::shared_ptr<cruthu::Node> significantNode(teraGen->GetSignificantNode());

    std::vector<std::shared_ptr<cruthu::IIndexer>> indexers;
    for(const auto indexer : this->mSettings.Indexers) {
        indexers.push_back(indexer.Factory->DLGetInstance());
    }
    std::vector<std::shared_ptr<cruthu::Node>> indexedNodes(indexers.at(0)->Index(nodes));

    std::shared_ptr<cruthu::ITera> tera(this->mSettings.Tera.Factory->DLGetInstance());
    tera->SetNodes(nodes);
    tera->SetIndexedNodes(indexedNodes);
    tera->SetSignificantNode(significantNode);

    for(const auto & formaF : this->mSettings.Formas) {
        std::shared_ptr<cruthu::IForma> forma(formaF.Factory->DLGetInstance());
        forma->SetNode(tera->GetIndexedNode());
        forma->Modify();

        std::cout << std::to_string(tera->GetIndexedNode()->GetHeight()) << std::endl;
    }

    this->CreateImage(tera);
}

TeraGen:

#ifndef CRUTHU_ITERAGEN_HPP
#define CRUTHU_ITERAGEN_HPP

#include <cruthu/Node.hpp>

#include <vector>

namespace cruthu {
class ITeraGen {
public:
    virtual ~ITeraGen() = default;

    virtual std::vector<std::shared_ptr<cruthu::Node>> Create() = 0;
    virtual std::shared_ptr<cruthu::Node> GetSignificantNode() = 0;
};
} // namespace cruthu
#endif

Tera:

#ifndef CRUTHU_ITERA_HPP
#define CRUTHU_ITERA_HPP

#include <cruthu/IIndexer.hpp>
#include <cruthu/Node.hpp>

#include <memory>
#include <vector>

namespace cruthu {
class ITera {
public:
    virtual ~ITera() = default;

    virtual void SetNodes(std::vector<std::shared_ptr<cruthu::Node>>& nodes) = 0;
    virtual void SetIndexedNodes(std::vector<std::shared_ptr<cruthu::Node>>& indexedNodes) = 0;
    virtual void SetSignificantNode(std::shared_ptr<cruthu::Node> significantNode) = 0;
    virtual std::vector<std::shared_ptr<cruthu::Node>>& GetNodes() = 0;
    virtual std::vector<std::shared_ptr<cruthu::Node>>& GetIndexedNodes() = 0;
    virtual std::shared_ptr<cruthu::Node> GetIndexedNode() = 0;
};
} // namespace cruthu
#endif

Indexer:

#ifndef CRUTHU_IINDEXER_HPP
#define CRUTHU_IINDEXER_HPP

#include <cruthu/Node.hpp>

#include <memory>
#include <vector>

namespace cruthu {
class IIndexer {
public:
    virtual ~IIndexer() = default;

    virtual std::vector<std::shared_ptr<cruthu::Node>> Index(std::shared_ptr<cruthu::Node> node) = 0;
    virtual std::vector<std::shared_ptr<cruthu::Node>> Index(std::vector<std::shared_ptr<cruthu::Node>>& nodes) = 0;
};
} // namespace cruthu
#endif

Формат:

#ifndef CRUTHU_IFORMA_HPP
#define CRUTHU_IFORMA_HPP

#include <cruthu/Node.hpp>

namespace cruthu {
class IForma {
public:
    virtual ~IForma() = default;

    virtual void SetNode(std::shared_ptr<cruthu::Node> node) = 0;
    virtual void Modify() = 0;
};
} // namespace cruthu
#endif

Я обновил и попытался добавить ссылки между ними, поэтому у них теперь есть ссылки местами.У меня все еще та же проблема.

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Это не (пока) ответ, но вопросы, чтобы определить проблему, так как недостаточно реализации.

Одна из возможных проблем (трудно сказать, не видя реализацию ...) заключается в том, чтоВы создаете узлы в верхней части функции Run():

std::vector<std::shared_ptr<cruthu::Node>> nodes(teraGen->Create());

Затем вы передаете эту функцию в качестве ссылки в этом вызове:

tera->SetNodes(nodes);

Что tera делает с узлами?Передача по ссылке означает, что счетчик shared_ptr: s не увеличивается.

Что делает this->CreateImage(tera)?

Используются ли узлы после завершения Run()?

0 голосов
/ 16 октября 2018

Я не мог понять, с комментариями сверху, это в основном моя проблема с неспособностью предоставить адекватную информацию.С учетом вышесказанного я переработал код, чтобы вместо этого передать объект cruthu::Tera в качестве общего указателя и раскрыть векторы как открытых членов класса.Это то, к чему я вернусь позже, так как эта реализация меня не устраивает.

Код на github , к сожалению, это моя дипломная работа, поэтому я могбольше не жди.

Если люди захотят еще попытаться ответить, я с ними поработаю.

0 голосов
/ 14 октября 2018

Как указано пользователем Remy Lebeau, приведите минимальный, полный и проверяемый пример.

Как вы заявили, вы передаете std::vector<std::shared_ptr<Node>> из одного класса в другой или из одной функции в другую и что онине обновляются и 0 инициализированы.Исходя из поведения, которое вы описываете, у меня тогда есть вопрос к вам, я публикую его как ответ, так как это было бы слишком долго для комментария.

Является ли объявление / определение вашей функции, которое принимает вектор илиобщие указатели выше выглядят примерно так:

void someFunc( std::vector<shared_ptr<Node> nodes ) { ... }

или это выглядит примерно так:

void someFunc( std::vector<shared_ptr<Node>& nodes ) { ... }

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

...