rob*_*ene 3 c++ tree abstract-class stl incomplete-type
几天前,我自己尝试用与STL容器相同的样式编写基本树实现.现在我正在尝试在我的代码中使用它,但是有两件事看起来不起作用std::vector.即,使用不完整类型和使用抽象类型.
如何修复我的树实现以获得此功能?我试着简化我的代码,主要向您展示相关部分.
TEST.CPP
#include "util/tree.hpp"
#include <vector>
struct IncompleteType;
class AbstractType
{
public:
virtual void do_something() = 0;
};
class Test
{
public:
Test() = default;
private:
tree<IncompleteType> incompleteTree;
std::vector<IncompleteType> incompleteVector;
tree<AbstractType> abstractTree;
std::vector<AbstractType> abstractVector;
};
struct IncompleteType
{
int completed;
};
Run Code Online (Sandbox Code Playgroud)
util/tree.hpp(浓缩)
template <class T, class Alloc = std::allocator<T> >
class tree
{
public:
typedef Alloc allocator_type;
typedef typename Alloc::value_type value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename Alloc::difference_type difference_type;
typedef typename Alloc::size_type size_type;
class node
{
public:
value_type data;
const std::vector<std::unique_ptr<node> >& get_children() const { return children_; }
node* get_parent() const { return parent_; }
node* get_right() const { return right_; }
bool operator== (const node&) const;
size_t size() const;
bool has_ancestor(const node* n) const { return parent_ != nullptr && (parent_ == n || parent_->has_ancestor(n)); }
friend class tree;
protected:
std::vector<std::unique_ptr<node> > children_;
node* parent_ = nullptr;
node* right_ = nullptr;
node() = default;
node(value_type data) : data(data) {}
};
class iterator
{
// ...
};
class const_iterator
{
// ...
};
tree() = default;
tree(const tree&) = default;
tree& operator= (const tree&) = default;
// iterators begin(), etc ...
// operators ...
// size(), empty(), ...
node* get_root() { return &root_; }
const node* get_root() const { return &root_; }
node* add_new_node(const value_type& val) { return add_new_node_to(&root_, val); }
node* add_new_node_to(node*, const value_type&);
bool prune_node(node*&);
private:
node root_;
};
Run Code Online (Sandbox Code Playgroud)
在编译时g++ -O3 -Wall -Wextra -pedantic -std=c++11 test.cpp,我得到以下输出:
In file included from test.cpp:1:0:
util/tree.hpp: In instantiation of ‘class tree<IncompleteType>::node’:
util/tree.hpp:138:7: required from ‘class tree<IncompleteType>’
test.cpp:19:30: required from here
util/tree.hpp:28:14: error: ‘tree<T, Alloc>::node::data’ has incomplete type
value_type data;
^
test.cpp:6:8: error: forward declaration of ‘tree<IncompleteType>::value_type {aka struct IncompleteType}’
struct IncompleteType;
^
In file included from test.cpp:1:0:
util/tree.hpp: In instantiation of ‘class tree<AbstractType>::node’:
util/tree.hpp:138:7: required from ‘class tree<AbstractType>’
test.cpp:21:30: required from here
util/tree.hpp:47:3: error: cannot allocate an object of abstract type ‘AbstractType’
node(value_type data) : data(data) {}
^
test.cpp:8:7: note: because the following virtual functions are pure within ‘AbstractType’:
class AbstractType
^
test.cpp:11:15: note: virtual void AbstractType::do_something()
virtual void do_something() = 0;
^
In file included from test.cpp:1:0:
util/tree.hpp:28:14: error: cannot declare field ‘tree<AbstractType>::node::data’ to be of abstract type ‘AbstractType’
value_type data;
^
test.cpp:8:7: note: since type ‘AbstractType’ has pure virtual functions
class AbstractType
^
Run Code Online (Sandbox Code Playgroud)
我的树有这些类型的问题,而std::vector没有.我可以看到它与我在节点中存储数据的方式有关,但是当我试图找到正确的方法时,我正在画一个空白......如果不是类型的话,我该如何存储value_type?
由于类型不完整,编译器无法确定其大小.由于需要通过值存储对象的大小,编译器会对它抱怨.如果必须处理不完整的类型,则需要使用指针容器.例如,Test你可以使用std::vector<std::unique_ptr<IncompleteType>>或std::vector<IncompleteType*>.
您的代码中还有另一个问题.因为你试图按值存储它tree而vector失败AbstractClass.由于它具有纯虚函数,因此在创建时无法实例化Node.