我有一个简单的层次结构树结构,其基类Node代表一个节点。节点可以是另一种特定类型(子类化)。
class Node {
vector<Node*> childs;
// simple node manipulation methods
const vector<Node*>& getChildren() { return childs; }
}
我有几个Node
的子类:
class FacultyNode : public Node; ...
class DepartmentNode : public Node; ...
假设我知道教师节点的所有孩子都是DepartmentNode
类型,为了保存开发人员的工作,我打算做类似的事情
vector<DepartmentNode*> FacultyNode::getDepartments() {
vector<Node*> tmp = this->getChildren();
vector<DepartmentNode*> a;
a.reserve(tmp.size());
for (int i = 0; i < tmp.size(); i++) {
a.push_back(static_cast<DepartmentNode*>(tmp[i]));
}
return a;
}
但这需要O(n)
,每次调用时都会创建新的矢量对象。
有没有更好的方法呢?
答案 0 :(得分:4)
你真的需要复制载体吗?如果你不需要,你可以编写一个迭代器,当用户请求项目时,即在操作符*上进行转换。
MyIterator FacultyNode::getDepartmentsBegin() {
vector<Node*>& tmp = this->getChildren();
return MyIterator(tmp.begin());
}
MyIterator FacultyNode::getDepartmentsEnd() {
vector<Node*>& tmp = this->getChildren();
return MyIterator(tmp.end());
}
struct MyIterator {
vector<DepartmentNode*>::iterator m_it;
MyIterator(vector<DepartmentNode*> it) : m_it(it) {}
Department * operator*() { return (Department*)*it; }
void operator++() { m_it++; }
// in the same way, forwarding to m_it, implement other needed iterators.
// ...
};
希望它澄清我的意思。
答案 1 :(得分:1)
也许您可以将Node
变成模板?
template<typename T>
class Node {
vector<T*> childs; // I think a Boost.PtrContainer would be better
// simple node manipulation methods
const vector<T*>& getChildren() { return childs; }
}
class FacultyNode : public Node<DepartmentNode>;
答案 2 :(得分:0)
正如James McNellis在下面的评论中指出的那样,以下是不安全的(他更加明确)。我不会自己使用它,即使我不知道为什么它会引发未定义的行为 - 也许我应该ask this in a question
由于您在数组中存储指针,并假设您可以更改函数的返回类型,那么您可以这样做:
const vector<DepartmentNode*>* FacultyNode::getDepartments() {
vector<Node*> tmp = this->getChildren();
return reinterpret_cast<vector<DepartmentNode*>*>(&tmp);
}