我知道,除非确实需要,否则必须避免使用现代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);
}
如果您要运行,我将在下面提供其余代码。您可能要使用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;
}
答案 0 :(得分:3)
我知道除非真正需要,否则必须避免使用现代C ++中的指针。
那是不对的。您可能会听到的是,如果您的要求符合标准化的模式/解决方案,例如unique_ptr
,则应避免使用原始(裸露的)指针。
很显然,我想更改指针本身(参考ptr)。想知道它们中的任何一个是否有优点,或者不应该使用它们,而必须使用const reference(现代方式)编写。
如果要具有输出参数,则有很多方法可以实现:
struct
,std::tuple
或使用结构化绑定的多个返回值。在所有情况下都没有一种最佳方法。您使用哪一种取决于您,以及如何使用该功能。在某些情况下,它还取决于项目的编码样式准则(例如,在引用还是指针的情况下)。例如:
f(a)
与f(&a)
)。必须使用const引用(现代方式)编写。
顺便说一句,请注意,您没有编写const
引用,而只是编写了对Note *
的引用。它不是“现代C ++”:引用是第一个C ++标准的一部分。
答案 1 :(得分:2)
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;
};
或
struct Node
{
int data;
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
};
您的display
函数不需要所有权,因此您将节点作为指针(或引用)传递
void display(Node *root)
{
if (root != nullptr)
{
display(root->left);
cout << root->data << " ";
display(root->right);
}
}
因为您不打算更改它,所以我会使用const ref:
void display(const Node &root)
{
if(root.left != nullptr) {
display(*root.left);
}
cout << root.data << " ";
if(root.right != nullptr) {
display(*root.right);
}
}
您insert_ref_to_ptr
是一个非常糟糕的构造,因为不清楚它是否转移任何所有权,也不清楚它在内部调用create(data)
并使用new
创建一个Node。
创建内容如下:
std::unique_ptr<Node> create(int data)
{
auto node = std::make_unique<Node>();
node->data = data;
return std::move(node);
}
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);
}