传递std :: shared_ptr的std :: vector,而不更新对象

时间:2018-10-13 23:21:25

标签: c++ c++11 memory

好的,我可能做错了,但是我机智。

我有一个我的节点类的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 /已初始化。

需要注意的是,我将数据传递到函数中并仅返回std::vector<std::shared_ptr<Node>>,这是我认为的问题,我不确定如何正确地传递shared_ptr的容器,这样我就不会复制。

如果需要更多信息,请告诉我。我正在寻找我能理解的示例或参考。

对不起,该代码并不美观,我使用动态加载的库来保存它。

完成工作的功能:

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

索引器:

#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 :(得分:0)

如用户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 ) { ... }

我问这是因为,如果您通过值传递容器(而不是通过引用传递容器)会有所不同。

答案 1 :(得分:0)

(这还不是)答案,但是由于没有提供足够的实施方法,因此存在一些问题来确定问题所在。

一个可能的问题(很难说没有看到实现...)是您在Run()函数顶部创建了节点:

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

然后在该调用中将该函数传递为引用:

tera->SetNodes(nodes);

tera对节点有何作用?通过引用传递意味着shared_ptr:s的计数不会增加。

this->CreateImage(tera)会做什么?

Run()完成之后是否使用了节​​点?

答案 2 :(得分:0)

我无法接受上面的评论,这主要是我无法提供足够信息的问题。 话虽如此,我重新设计了代码,而是将cruthu::Tera对象作为共享指针传递给了对象,并将向量作为类的公共成员公开。这是我稍后会重新讨论的事情,因为我对此感到不满意。

代码在github上,很遗憾,这是我的论文工作,所以我不能再等待了。

如果人们感到仍然想尝试答案的愿望,我将与他们合作。