【发布时间】:2020-03-03 09:24:03
【问题描述】:
我有一个 Tree 类,在这个类中我有一个私有的 Node 类(嵌套)。 Tree 类当然是一个模板类。
问题是,当我想将一个树子插入到一个没有确切子代数的树父代中时,我收到一个类型不兼容的错误以进行转换。
这是我的代码:
tree.hpp
#ifndef TREE_HPP
#define TREE_HPP
#include <iostream>
#include <cstddef>
template <typename T, char N>
class Tree {
private:
class Node;
Node* _info;
public:
Tree();
Tree(T, char);
Tree(const Tree&) = delete; // copy constructor
Tree& operator= (const Tree&) = delete; // assignement by copy constructor
Tree (Tree&&); // transfer constructor
Tree& operator= (Tree&&); // assignement by transfer constructor
~Tree() {delete _info;}
bool ins(char, Tree&);
Tree* fils(char);
};
template <typename T, char N>
Tree<T, N>::Tree()
: _info(nullptr) {}
template <typename T, char N>
Tree<T, N>::Tree(T data, char size) {
Node* node = new Node(data);
_info = node;
}
template <typename T, char N>
Tree<T, N>::Tree(Tree&& t) {
_info = t._info;
t._info = nullptr;
}
template <typename T, char N>
Tree<T, N>& Tree<T, N>::operator= (Tree&& t) {
if (&t != this) {delete _info; _info = t._info; t._info = nullptr;}
return *this;
}
template <typename T, char N>
bool Tree<T, N>::ins(char index, Tree& childTree){
if (_info){
_info->getChildren()[index] = &childTree;
return true;
}
return false;
}
template <typename T, char N>
Tree<T,N>* Tree<T, N>::fils(char index){
return _info->getChildren()[index];
}
template <typename T, char N>
class Tree<T, N>::Node {
private:
T _data;
Tree* _children[N];
bool _isWord;
public:
Node();
Node(T);
Tree** getChildren() {return this->_children;}
T getData(){return this->_data;}
~Node() = default;
};
template <typename T, char N> // Node class default constructor
Tree<T,N>::Node::Node(){
_data = 0;
_children = nullptr;
_isWord = false;
}
template <typename T, char N> // Node class constructor
Tree<T,N>::Node::Node(T data){
_data = data;
_isWord = false;
for (char i = 0; i < N; i++)
_children[i] = NULL;
}
#endif
main.cpp
#include <iostream>
#include <cstddef>
#include "tree.hpp"
#define SIZE 5
#define display(x) std::cout<<x<<std::endl
int main() {
Tree<char,SIZE> n1('A',SIZE);
Tree<char,SIZE> n1_1('B',SIZE); // works fine
Tree<char,10> n1_2('C',10); // sends the error
n1.ins(0,n1_1);
n1.ins(1,n1_2);
return 0;
}
错误是:
main.cpp: In function ‘int main()’:
main.cpp:16:12: error: cannot convert ‘Tree<char, '\012'>’ to ‘Tree<char, '\005'>&’
16 | n1.ins(1,n1_2);
| ^~~~
| |
| Tree<char, '\012'>
In file included from main.cpp:4:
tree.hpp:80:40: note: initializing argument 2 of ‘bool Tree<T, N>::ins(char, Tree<T, N>&) [with T = char; char N = '\005']’
80 | bool Tree<T, N>::ins(char index, Tree& childTree){
|
我也愿意接受有关改进此代码的方法的建议。
谢谢...
【问题讨论】:
-
N的变化意味着类是不同的类型。当您显然不想要固定数量的孩子时,我看不到您从拥有固定数量的孩子中得到什么。我会删除模板N并动态分配孩子的数量。如果允许,请使用std::vector。 -
为了完整起见,您应该将
Node的定义添加到问题中。旁注:看看你是否可以对用户隐藏Node,绝对不要让他们引用一个。当用户意外释放或损坏节点时,它会很糟糕,因为它破坏了整个数据结构。 -
@user4581301 我不太明白你在说什么,但是当我想使用 Node 对象时,我可以向 Node 发送一个 const 引用,而这种情况下我不修改 node,因为它是 const。
-
假设:
Node包含一个大小为N的子节点数组。这意味着Node<5>与Node<10>的大小不同,并且不再兼容。您可以做的是创建一个非模板化的Base_Node类,Node继承自该类。Base_Node声明了Node的所有功能,但没有实现它们。Tree存储并看到指向Base_Node的指针,并且不知道有多少孩子,因此实际上指向的是什么类型的Node。这解决了兼容性问题,但让Tree很难确定要构造哪个Node。 -
以上将动态分配的数量保持在最低限度,但不能很好地扩展。
标签: c++ templates tree insertion