构造函数和常量引用
Constructor and const reference
我现在正在学习 C++(大约 2 天前开始),我在编写 Node.js 的 Copy C'tor 时遇到了一些麻烦。
节点是一个 class 如下:
template <class T>
class Node {
T* data;
Node<T>* next;
friend class Iterator<T>;
public:
Node():data(NULL),next(NULL){}
Node(const T& data):data(NULL),next(NULL){
T* copy = new T(data);
this->data = copy;
}
Node(const Node& node):data(NULL),next(NULL){
Node<T> dummy;
dummy.data = node.data;
dummy.next = node.next;
Node<T>* head=new Node(*dummy);
*this = *head;
while(dummy.next != NULL) {
dummy = *(dummy.next);
head = head->next;
head = new Node(*dummy);
}
}
注意:我有 operator* 所以 *dummy 结果是 T 类型。
另注:我的public和private字段可能有误-但我会稍后处理。
吐了一口之后,请看Copy C'tor
它获得了 Node 的常量引用,然后我尝试创建一个指向它的指针。编译器输出错误:
Node<T>* dummy= &node;
结果 invalid conversion from 'const Node<int>*' to 'Node<int>*'
(我有一个简短的主要尝试创建 Node<int>
)。
好的,看来我无法创建指向 const 的指针,所以我尝试手动复制它的字段,如代码所示。
当我 运行 Eclipse 调试器并检查它是否有效时 - 它确实有效。
但是,当我继续执行步骤时,D'tor 在 head 上被调用(在复制构造函数的末尾),结果一切都崩溃了。
所以我不知道下一步该做什么,即使我走对了路。
我应该如何制作拷贝构造函数?我想我明白为什么 D'tor 被称为(我创建了一些东西,然后在块的末尾,一些东西被摧毁了 - 对吧?),但我不知道如何让它正确。
复制构造函数的目的是为传递的对象创建一个'exact copy'。因此,根据 data
和 next
指针的语义,您可以使用初始化列表简单地分配它们:
Node(const Node& node): data(node.data), next(node.next) {}
因为这就像预期的默认行为(复制成员),您可以简单地省略复制构造函数,编译器将默认生成一个合适的。
请注意,您绝对可以创建一个指向 const
对象的指针:编译器抱怨的是您的指针的类型声明在此过程中丢失了 const
位。
第二个注意事项:对于深度复制,您可以使用类似的东西:
Node(const Node& node):
data(node.data == NULL? NULL: new T(*node.data)),
next(node.next == NULL? NULL: new Node(*node.next)) {}
当然,在那种深度复制场景中,您的容器正在使用 "ownership" 成员字段(这提示了一个问题:为什么它们首先是指针?)因此应该注意正确地 delete
它们在析构函数中。
您发布的代码与您引用的语句不完全匹配,错误为:
Node<T>* dummy= &node;
但无论如何,你可以这样做:
const Node<T>* dummy= &node;
因为 node
是 const
,任何指向它的引用或指针也必须是 const
。您也无法在 node
上调用非常量方法,因此您为数据访问器创建的任何方法都必须是正确的。
我现在正在学习 C++(大约 2 天前开始),我在编写 Node.js 的 Copy C'tor 时遇到了一些麻烦。 节点是一个 class 如下:
template <class T>
class Node {
T* data;
Node<T>* next;
friend class Iterator<T>;
public:
Node():data(NULL),next(NULL){}
Node(const T& data):data(NULL),next(NULL){
T* copy = new T(data);
this->data = copy;
}
Node(const Node& node):data(NULL),next(NULL){
Node<T> dummy;
dummy.data = node.data;
dummy.next = node.next;
Node<T>* head=new Node(*dummy);
*this = *head;
while(dummy.next != NULL) {
dummy = *(dummy.next);
head = head->next;
head = new Node(*dummy);
}
}
注意:我有 operator* 所以 *dummy 结果是 T 类型。
另注:我的public和private字段可能有误-但我会稍后处理。
吐了一口之后,请看Copy C'tor
它获得了 Node 的常量引用,然后我尝试创建一个指向它的指针。编译器输出错误:
Node<T>* dummy= &node;
结果 invalid conversion from 'const Node<int>*' to 'Node<int>*'
(我有一个简短的主要尝试创建 Node<int>
)。
好的,看来我无法创建指向 const 的指针,所以我尝试手动复制它的字段,如代码所示。 当我 运行 Eclipse 调试器并检查它是否有效时 - 它确实有效。 但是,当我继续执行步骤时,D'tor 在 head 上被调用(在复制构造函数的末尾),结果一切都崩溃了。 所以我不知道下一步该做什么,即使我走对了路。
我应该如何制作拷贝构造函数?我想我明白为什么 D'tor 被称为(我创建了一些东西,然后在块的末尾,一些东西被摧毁了 - 对吧?),但我不知道如何让它正确。
复制构造函数的目的是为传递的对象创建一个'exact copy'。因此,根据 data
和 next
指针的语义,您可以使用初始化列表简单地分配它们:
Node(const Node& node): data(node.data), next(node.next) {}
因为这就像预期的默认行为(复制成员),您可以简单地省略复制构造函数,编译器将默认生成一个合适的。
请注意,您绝对可以创建一个指向 const
对象的指针:编译器抱怨的是您的指针的类型声明在此过程中丢失了 const
位。
第二个注意事项:对于深度复制,您可以使用类似的东西:
Node(const Node& node):
data(node.data == NULL? NULL: new T(*node.data)),
next(node.next == NULL? NULL: new Node(*node.next)) {}
当然,在那种深度复制场景中,您的容器正在使用 "ownership" 成员字段(这提示了一个问题:为什么它们首先是指针?)因此应该注意正确地 delete
它们在析构函数中。
您发布的代码与您引用的语句不完全匹配,错误为:
Node<T>* dummy= &node;
但无论如何,你可以这样做:
const Node<T>* dummy= &node;
因为 node
是 const
,任何指向它的引用或指针也必须是 const
。您也无法在 node
上调用非常量方法,因此您为数据访问器创建的任何方法都必须是正确的。