gpt4 book ai didi

c++存储对节点内数据对象的引用而不复制数据

转载 作者:行者123 更新时间:2023-11-28 01:45:17 25 4
gpt4 key购买 nike

我真的是 c++ 的新手,我尝试构建一个基本的 LinkedList 节点只是为了基本上理解整个指针/引用的事情。

我正在尝试存储对要传递给我的节点类中的构造函数的对象的引用。

我还创建了一个复制构造函数,以便查看节点何时被复制(用于测试目的)

节点代码如下:

#include <iostream>
using namespace std;


template<typename T>
struct Node {

Node(const T &d): data(d), next(nullptr), prev(nullptr){
;
cout << "created Node obj" << endl;
};

Node (const Node &node) {
cout << "Copied Node obj" << endl;
}

void setNext(Node *next){ this->next = next; };
void setPrev(Node *prev){ this->prev = prev; };
Node* getNext(){ return next ;};
Node* getPrev(){ return prev ;};
T& getData(){ return data ;};

private:
Node *next;
Node *prev;
T data;

};

而且我还有这个用于测试的基本代码:

#include <iostream>
#include <vector>
#include "Node.h"

using namespace std;
int main() {
vector <int> v1 {1};

Node< vector<int> > n1{v1}; // (1)

Node < Node< vector<int> > > nn1{n1}; // (2)
Node< vector<int> > & n1ref = nn1.getData();
return 0;
}

所以首先在第 (1) 行之后使用调试器,我已经看到 vector 类的复制构造函数被我无缘无故地使用了。

所以我也用第 (2) 行进行了测试 - 实际上节点内的节点正在被复制 - 有人可以澄清为什么节点和 vector 被复制,尽管我已经将它们作为引用传递了吗?

顺便说一句,运行 main 的输出是:

created Node obj
Copied Node obj
created Node obj

更新首先感谢大家的 promise ,我正在考虑有关存储指针甚至拷贝的注释(正如我现在所见,有时这可能更有意义)

但上面的代码主要是针对指针/引用的实践,所以至少现在我想坚持使用引用成员。

在尝试@underscore_d 将成员类型更新为 T& 的建议后,我得到了以下结果:

首先,IDEA (CLION) 让我更新复制构造函数 - 现在它必须更新初始化列表中的数据成员。我猜这是因为应该在创建时分配引用 - 有人可以批准/澄清这一点吗?

所以代码如下:

template<typename T>
struct Node {

Node(const T & d): data(d), next(nullptr), prev(nullptr){

cout << "created Node obj" << endl;
};

Node (const Node &node): data(node.getData()) {
cout << "Copied Node obj" << endl;
}

void setNext(Node *next){ this->next = next; };
void setPrev(Node *prev){ this->prev = prev; };
Node* getNext() const { return next ;};
Node* getPrev() const { return prev ;};
T& getData() const { return data ;};

private:
Node *next;
Node *prev;
T& data;

};

现在的问题是编译失败(使用相同的主类)并出现以下错误:

error: binding 'const std::vector<int>' to reference of type 'std::vector<int>&' discards qualifiers

我不完全理解,如有任何帮助,我们将不胜感激。再次感谢您的帮助 - 非常感谢。

最佳答案

我的 C++ 生锈了,但节点内的值被复制的事实,我相信,是因为你定义了属性:

T data;

T类的对象.所以在 (1) 中,当节点被创建时,它将引用参数(我的意思是 const T &d )复制到属性 data 中正如您在构造函数中声明的那样 data(d) .

也许是 T* data作为属性会有所帮助。在这种情况下,您有以下选择:

一个。更改构造函数以接收 T* 作为参数而不是引用 T&(以及正确的相关代码)

在构造函数中接收 T&,但在内部将引用转换为指针。为此,写data(&d)作为构造函数中的初始化。并且记得改成T& getData(){ return *data ; } (以及任何相关的)

关于为什么显示:

created Node obj
Copied Node obj
created Node obj

这是因为:

  • 在 (1) 中显示了第一个“创建节点对象”,因为 Node< vector<int> > n1{v1};创建节点 n1。
  • 在 (2) 中,它显示了另外两条消息,因为:
    • Node < Node< vector<int> > > nn1{n1};复制节点 n1因为data(d)其中 d=n1 并显示“复制的节点对象”
    • 之后,在显示“create Node obj”的地方执行构造函数的其余部分。

-- 编辑:

我赞成@underscore_d 使用指针而不是引用,你会避免很多问题:)

(@underscore_d,请不要删除您的评论,它们是解释性的)

-- 编辑 2:

如果我没记错的话,关于你的问题:

error: binding 'const std::vector<int>' to reference of type 'std::vector<int>&' discards qualifiers

它的意思是:“你有一个变量 const blahblah - 声明你不会修改它 - 并且你将它分配给一个变量'not const'所以你声明< em>也许你会修改它。所以不。我不允许你可能修改它。“

特别是在您的代码中,这是因为您在 Node 中有一个非常量成员(注意它是一个引用,在下面键入):

T& data;

在你的构造函数中你有一个 const参数,你不会复制,而是引用它:

Node(const T & d): data(d)
Node (const Node &node): data(node.getData())

C++ 中的引用 不是指针,而是相同的对象。所以实际上你在一个地方有一个“const blahblah”,在另一个地方有一个“blahblah”。您可以将非常量转换为常量,但反之则不行。你可以这样做:

int a = 5;         // You can modify it
const int& b = a ; // and who cares if you are not going to
// modify 'b' (which is 'a' at the same time)

但不是:

const int a = 5; // You can't modify it
int& b = a; // and no, we are not going to let you modify it
// because you would modify 'a', but 'a' is const.

解决方案?要么摆脱 const 参数,要么尝试使 const 成为 Node 的成员(但您将无法修改其中的数据!)。

希望我没记错:)

关于c++存储对节点内数据对象的引用而不复制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45417737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com