【问题标题】:Compiler error while using shared_ptr with a pointer to a pointer将 shared_ptr 与指向指针的指针一起使用时出现编译器错误
【发布时间】:2019-09-03 06:02:47
【问题描述】:

我是在 C++ 中使用智能指针的新手,我当前的问题是我正在将 C 代码转换为 C++ (C++11/14/17),并且我在理解使用带有指针指针的 shared_ptr 时遇到了一些问题。我得出了一个玩具示例,我相信它可以说明问题

下面是头文件

#include <memory>
using std::shared_ptr;

struct DataNode
{
  shared_ptr<DataNode> next;
} ;


 struct ProxyNode
 {
   shared_ptr<DataNode> pointers[5];
 } ;


 struct _test_
 {
   ProxyNode** flane_pointers;
  };

以及实际代码test.cpp

#include <stdint.h>
#include "test.h"


shared_ptr<DataNode> newNode(uint64_t key);

shared_ptr<ProxyNode> newProxyNode(shared_ptr<DataNode> node);

int main(void)
{
  // Need help converting this to a C++ style calling
  ProxyNode** flane_pointers = (ProxyNode**)malloc(sizeof(ProxyNode*) * 100000);
  // Here is my attempt (incomplete)
  ProxyNode** flane_pointers = new shared_ptr<ProxyNode> ?
  shared_ptr<DataNode> node = newNode(1000);
  flane_pointers[1] = newProxyNode(node)
} 

shared_ptr<ProxyNode> newProxyNode(shared_ptr<DataNode> node) 
{

  shared_ptr<ProxyNode> proxy(new ProxyNode());
 return proxy;
}

shared_ptr<DataNode> newNode(uint64_t key) 
{
 shared_ptr<DataNode> node(new DataNode());
 return node;
}

我收到这些编译器错误 -

 test.cpp: In function ‘int main()’:
 test.cpp:12:42: error: cannot convert ‘std::shared_ptr<ProxyNode>’ to  ‘ProxyNode*’ in assignment
  flane_pointers[1] = newProxyNode(node)

编译

  g++ -c -g test.h test.cpp

g++ 版本为 7.3.0(在 Ubuntu 18 上)

我需要帮助将 C 风格 malloc 分配转换为 C++ 风格,调用指向指针的指针,然后如何修复编译器错误。如果看起来我遗漏了一些明显的东西,我深表歉意。

【问题讨论】:

    标签: c++ compiler-errors g++ shared-ptr smart-pointers


    【解决方案1】:

    如果这个ProxyNode** flane_pointers; 应该是ProxyNode 的矩阵,那么最简单的方法是创建包含ProxyNode 的向量,如下所示:

    struct DataNode
    {
        std::shared_ptr<DataNode> next;
    };
    
    
    struct ProxyNode
    {
        // here instead of C style array you can use std::array
        std::shared_ptr<DataNode> pointers[5];
    };
    
    TEST(xxx, yyy) {
        std::vector<std::vector<ProxyNode> > matrixOfProxyNodes;
        // insert empty vector of ProxyNode
        matrixOfProxyNodes.push_back(std::vector<ProxyNode>());
        // insert ProxyNode to the first vector of ProxyNodes
        matrixOfProxyNodes[0].push_back(ProxyNode());
        // insert shared_ptr to DataNode in position 0, 0 of matrix of ProxyNodes
        matrixOfProxyNodes[0][0].pointers[0] = std::make_shared<DataNode>();
    }
    

    如果你真的需要指向指针的指针(但我真的不明白这样做的目的)你可以这样做:

        // create shared pointer to shared pointer to ProxyNode
        // and initialize it to nullptr
        std::shared_ptr<std::shared_ptr<ProxyNode> > ptr2ptr2ProxyNode(nullptr);
        // dynamically create new shared_ptr to ProxyNode
        ptr2ptr2ProxyNode.reset(new std::shared_ptr<ProxyNode>(nullptr));
        // dynamically create ProxyNode
        ptr2ptr2ProxyNode->reset(new ProxyNode());
        (*ptr2ptr2ProxyNode)->pointers[0] = std::make_shared<DataNode>();
    

    请注意,std::shared_ptr 的行为与原始指针不完全相同,例如,您不应为 shared_ptroperator new[] 分配内存。 Here is explained why.

    我还看到您可能想要实现某种列表或其他链。 std::shared_ptr 可能会受到 cyclic dependency 的影响,因此请小心并在需要时使用 std::weak_ptr

    【讨论】:

    • flane_pointers 不是 ProxyNode(s) 的矩阵,而是它的一维数组。
    • 我认为我不能使用向量,因为遗留代码需要使用索引来获取元素。所以基于数组的方法是必要的。你能解释一下 ptr2ptr2ProxyNode 是什么吗?不清楚。
    • 当然你可以使用std::vector。它们使用索引、偏移量、元素地址等与您的遗留代码兼容。这是解释here
    • 谢谢。我会试一试。这是最佳做法吗?使用向量和搜索索引、偏移量和地址?
    • 最佳实践是定义一个具有完全符合您的目的的接口的类(但您需要首先了解该目的,当您从 C 转换代码时并不总是很明显)。一开始最好使用std::vector 而不是C 风格的T* arr; 数组。 std::vector 为您提供了使用方括号运算符 elem[i]; 迭代器(具有指针语法)访问元素的接口,甚至是对底层 data 的 C 样式访问。
    猜你喜欢
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 2019-09-02
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    相关资源
    最近更新 更多