我定义了一个通用的树节点类,如下所示:
template<class DataType>
class GenericNode
{
public:
GenericNode() {}
GenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
size_t getChildCount() const
{ return mChildren.size(); }
const GenericNode * getChild(size_t idx) const
{ return mChildren[idx]; }
GenericNode * getChild(size_t idx)
{ return mChildren[idx]; }
void addChild(GenericNode * inItem)
{ mChildren.push_back(inItem); }
private:
DataType mData;
typedef std::vector<GenericNode*> Children;
Children mChildren;
};
typedef GenericNode<std::string> TreeItemInfo;我想通过使子指针类型可定制来使它更通用。例如允许使用智能指针类型。我天真地尝试了一下:
template<class DataType, class ChildPtr>
class GenericNode
{
public:
GenericNode() {}
GenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
size_t getChildCount() const
{ return mChildren.size(); }
const ChildPtr getChild(size_t idx) const
{ return mChildren[idx]; }
ChildPtr getChild(size_t idx)
{ return mChildren[idx]; }
void addChild(ChildPtr inItem)
{ mChildren.push_back(inItem); }
private:
DataType mData;
typedef std::vector<ChildPtr> Children;
Children mChildren;
};
typedef GenericNode<std::string, GenericNode<std::string > * > TreeItemInfo;但是,这当然不起作用,因为我需要为第二个参数指定第二个参数,为第二个参数指定第二个参数,依此类推。进入永恒。
有没有办法解决这个难题?
编辑
我根据@Asaf的回答找到了一个解决方案。对于感兴趣的人,下面是完整的代码示例(欢迎评论)。
EDIT2
我修改了接口,以便在外部始终使用原始指针。
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <assert.h>
template <class PointeeType>
struct NormalPointerPolicy
{
typedef PointeeType* PointerType;
static PointeeType* getRaw(PointerType p)
{
return p;
}
};
template <class PointeeType>
struct SharedPointerPolicy
{
typedef boost::shared_ptr<PointeeType> PointerType;
static PointeeType* getRaw(PointerType p)
{
return p.get();
}
};
template <class DataType, template <class> class PointerPolicy>
class GenericNode
{
public:
GenericNode() { }
GenericNode(const DataType & inData) : mData(inData) { }
typedef GenericNode<DataType, PointerPolicy> This;
typedef typename PointerPolicy<This>::PointerType ChildPtr;
const This * getChild(size_t idx) const
{ return PointerPolicy<This>::getRaw(mChildren[idx]); }
This * getChild(size_t idx)
{ return PointerPolicy<This>::getRaw(mChildren[idx]); }
void addChild(This * inItem)
{
ChildPtr item(inItem);
mChildren.push_back(item);
}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
private:
DataType mData;
std::vector<ChildPtr> mChildren;
};
typedef GenericNode<std::string, NormalPointerPolicy> SimpleNode;
typedef GenericNode<std::string, SharedPointerPolicy> SmartNode;
int main()
{
SimpleNode simpleNode;
simpleNode.addChild(new SimpleNode("test1"));
simpleNode.addChild(new SimpleNode("test2"));
SimpleNode * a = simpleNode.getChild(0);
assert(a->data() == "test1");
const SimpleNode * b = static_cast<const SimpleNode>(simpleNode).getChild(1);
assert(b->data() == "test2");
SmartNode smartNode;
smartNode.addChild(new SmartNode("test3"));
smartNode.addChild(new SmartNode("test4"));
SmartNode * c = smartNode.getChild(0);
assert(c->data() == "test3");
SmartNode * d = static_cast<const SmartNode>(smartNode).getChild(1);
assert(d->data() == "test4");
return 0;
}发布于 2009-10-20 16:44:12
不是你想的那样。你应该在这里结合一些继承。尝试这样做,例如:
template <class PointeeType>
struct NormalPointerPolicy
{
typedef PointeeType* PointerType;
};
template <class PointeeType>
struct SmartPointerPolicy
{
typedef MySmartPtrClass<PointeeType> PointerType;
};
template <class DataType>
class BaseGenericNode
{
public:
BaseGenericNode() {}
BaseGenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
protected:
DataType mData;
};
template <class DataType, template <class> class PointerPolicy>
class GenericNode : public BaseGenericNode<DataType>
{
typedef typename PointerPolicy<BaseGenericNode<DataType> >::PointerType ChildPtr;
private:
typedef std::vector<ChildPtr> Children;
Children mChildren;
};GenericNode是实际的节点类型,它包含基本类型'BaseGenericNode‘。
基类型保存实际数据(及其相关功能),派生类保存到其他节点的链接。
对于指针的实际外观,有两个模板策略类,您可以这样使用它们:
GenericNode<int, NormalPointerPolicy> instance;
GenericNode<int, SmartPointerPolicy> instance;问题(或优势?)这种实现的一个特点是,具有一种指针的节点可以持有具有另一种指针的子节点。
https://stackoverflow.com/questions/1595647
复制相似问题