我读过隐藏在课堂上使用的实际容器类型是件好事。它会意外地(或有意地)编写符合实际容器类型(可能会更改和破坏先前代码)的代码,从而使代码更加健壮。
因此,这意味着这不是一个好主意;如果实施从std::vector
变为std::list
,事情将会中断:
class MyType {
public:
const std::vector<MyType*>& GetChildren() const;
std::vector<MyType*>& GetChildren();
const std::vector<MyType*>::size_type GetChildCount() const;
std::vector<MyType*>::size_type GetChildCount();
private:
MyType* _parent;
std::vector<MyType*> _children;
};
使用typedef
使其看起来像隐藏,但用户只需要查看鼠标悬停定义(至少在Visual Studio中)即可查看相应的实际类型和代码。更糟糕的是,编译器根本没有看到typedef
,它只是看到底层类型。
class MyType {
public:
typedef std::vector<MyType*> ChildContainer;
typedef ChildContainer::size_type ChildContainerSize;
const ChildContainer& GetChildren() const;
ChildContainer& GetChildren();
const ChildContainerSize GetChildCount() const;
ChildContainerSize GetChildCount();
private:
MyType* _parent;
ChildContainer _children;
};
问题:有没有办法隐藏底层容器类型,这样用户很难围绕它进行编码,而不是将STL容器包装成可能写得不好而且不需要包装器?
答案 0 :(得分:0)
有时您别无选择,只能显示基础容器类型。例如,对于像std :: vector v这样的随机访问的容器,我可以进行排序(v.begin(),v.begin()+ 10);而对于std :: list li,我只能做li.sort(),你怎么能隐藏容器类型,只使用迭代器?这些迭代器完全不兼容。此外,容器类型是软件设计中最基本的考虑因素之一,为什么要考虑更改容器类型的未来可能性?这通常意味着糟糕的设计和软件的重制。
答案 1 :(得分:-1)
您应该使用typedef和迭代器。然后,如果要更改容器,则可以因为用户仅依赖于迭代器。如果他们愿意,人们总是可以打破它,但是你正在暴露一种不打破的简单方法。
class MyType {
public:
typedef std::vector<MyType*> ChildContainer;
typedef ChildContainer::size_type ChildContainerSize;
typedef std::vector<MyType*> ChildContainerIter;
typedef std::vector<MyType*> ChildContainerCIter;
const ChildContainerCIter GetChildrenBegin() const { return _children.begin(); }
ChildContainerIter GetChildrenBegin() { return _children.begin(); }
const ChildContainerCIter GetChildrenEnd() const { return _children.end(); }
const ChildContainerSize GetChildCount() const;
private:
MyType* _parent;
ChildContainer _children;
};
并且没有办法真正完全隐藏它。编译器需要知道编译代码时的类型。