1

我现在正在学习 C++(从 2 天前开始),我在编写 Node.js 的 Copy C'tor 时遇到了一些麻烦。Node 是一个类,如下所示:

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 类型。

另一个注意事项:我的公共和私人领域可能是错误的 - 但我稍后会处理它。

在你吐了一点之后,让我们看看 Copy C'tor。

它获得了 Node 的 const 引用,然后我尝试创建一个指向它的指针。编译器输出错误: Node<T>* dummy= &node;结果invalid conversion from 'const Node<int>*' to 'Node<int>*'(我有一个简短的 main 试图创建Node<int>)。

好的,所以似乎我无法创建指向 const 的指针,所以我尝试手动复制它的字段,如代码所示。当我运行 Eclipse 调试器并检查它是否有效时 - 它确实有效。但是,当我继续执行步骤时,会直接调用 D'tor (在复制构造函数的末尾),结果一切都崩溃了。所以我不知道下一步该做什么,或者即使我的方式是正确的。

我应该如何制作复制构造函数?我想我理解为什么要调用 D'tor(我创造了一些东西,在块的末尾,一些东西被破坏了 - 对吗?),但我不知道如何使它正确。

4

2 回答 2

1

复制构造函数的目的是对传递的对象进行“精确复制”。因此,根据datanext指针的语义,您只需使用初始化列表分配它们:

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)) {}

当然,在那种深拷贝场景中,您的容器正在获取成员字段的“所有权”(这引发了一个问题:为什么它们首先是指针?)因此应该小心地将它们正确地delete放入析构函数中。

于 2015-06-12T00:00:52.373 回答
0

您发布的代码与您引用的错误语句不太匹配:

Node<T>* dummy= &node;

但无论如何,你可以这样做:

const Node<T>* dummy= &node;

因为nodeconst,任何指向它的引用或指针也必须是const。您也无法在 上调用非 const 方法node,因此您为数据访问器创建的任何方法都需要是 const 正确的。

于 2015-06-12T00:01:40.613 回答