我应该避免在现代 C++ 中引用指针吗?或者在这种特殊情况下也可以

Kar*_*ole 6 c++ pointers reference c++17

我知道除非确实需要,否则必须避免现代 C++ 中的原始指针(或更准确地说是new和)。delete我相信在图实现方面,指针非常有用。不过,我很高兴听到对此的评论。

我正在研究二叉搜索树并编写insert函数。我使用两种不同但相似的方法实现,一种使用指针,另一种使用指针引用。显然我想更改指针本身(参考 ptr)。想知道它们中的任何一个是否有优点,或者不应该使用它们,并且必须使用 const 引用或智能指针(现代方式)编写。

Node *insert_ptr(Node *root, int data)
{
    if (root == NULL)
        return create(data);
    else if (data < root->data)
        root->left = insert(root->left, data);
    else
        root->right = insert(root->right, data);
    return root;
}

void insert_ref_to_ptr(Node *&root, int data)
{
    if (root == NULL)
        root = create(data);
    else if (data < root->data)
        insert(root->left, data);
    else
        insert(root->right, data);
}
Run Code Online (Sandbox Code Playgroud)

如果您想运行,我将在下面提供其余的代码。您可能想用作1 3 6 8 10 14 13 4 7输入

struct Node
{
    int data;
    Node *left;
    Node *right;
};

void display(Node *root)
{
    if (root != NULL)
    {
        display(root->left);
        cout << root->data << " ";
        display(root->right);
    }
}

Node *create(int data)
{
    Node *node = new Node();
    node->data = data;
    node->left = node->right = NULL;
    return node;
}

int main()
{
    Node *root = NULL;
    vector<int> nodes;

    string line;
    int value;
    getline(cin, line);
    stringstream split(line);
    while (split >> value)
        nodes.push_back(value);
    /*
    root = insert_ptr(root, nodes[0]);
    for (int i = 1; i < nodes.size(); i++)
        insert_ptr(root, nodes[i]);
    */

    for (int i = 0; i < nodes.size(); i++)
        insert_ref_to_ptr(root, nodes[i]);
    display(root);
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

t.n*_*ese 4

that pointers in modern C++ must be avoided unless really needed 那是错误的。

new应该delete避免,您应该使用唯一和共享指针。

但是,如果不转移所有权,您仍然会通过引用或原始指针传递对象。

Node具有所有权关系,因此应该是:

struct Node
{
    int data;
    std::unique_ptr<Node> left;
    std::unique_ptr<Node> right;
};
Run Code Online (Sandbox Code Playgroud)

或者

struct Node
{
    int data;
    std::shared_ptr<Node> left;
    std::shared_ptr<Node> right;
};
Run Code Online (Sandbox Code Playgroud)

您的display函数不需要所有权,因此您将节点作为指针(或引用)传递

void display(Node *root)
{
    if (root != nullptr)
    {
        display(root->left);
        cout << root->data << " ";
        display(root->right);
    }
}
Run Code Online (Sandbox Code Playgroud)

由于您不打算更改它,我会选择 const ref:

void display(const Node &root)
{
    if(root.left != nullptr) {
        display(*root.left);
    }

    cout << root.data << " ";

    if(root.right != nullptr) {
        display(*root.right);
    }
}
Run Code Online (Sandbox Code Playgroud)

insert_ref_to_ptr是一个非常糟糕的构造,因为不清楚它是否转移任何所有权,也不清楚它create(data)在其中调用使用创建一个节点new

创建看起来像这样:

std::unique_ptr<Node> create(int data)
{
    auto node = std::make_unique<Node>();
    node->data = data;
    return std::move(node);
}
Run Code Online (Sandbox Code Playgroud)

函数是insert_ref_to_ptr这样的:

void insert_ref_to_ptr(std::unique_ptr<Node> &root, int data)
{
    if (root == nullptr)
        root = std::move(create(data));
    else if (data < root->data)
        insert(root->left, data);
    else
        insert(root->right, data);
}
Run Code Online (Sandbox Code Playgroud)