代码之家  ›  专栏  ›  技术社区  ›  dimba

向量、大小类型和封装

  •  4
  • dimba  · 技术社区  · 14 年前

    我有一个类具有类型为的私有数据成员 vector< A*> .

    类有两个实际使用的公共方法 vector<A*>::size_type 以下内容:

    1. 返回向量中元素数的方法
    2. 按索引返回向量中元素的方法

    我可以将以下typedef添加到类的公共部分:

    typedef vector::size_type size_t;

    但是imho它公开了太多关于类实现的细节。

    另一种方法是 size_t .

    你怎么认为?

    6 回复  |  直到 12 年前
        1
  •  4
  •   dirkgently    14 年前

    用朴素的旧 size_t 对于两个成员函数。

        2
  •  6
  •   David Rodríguez - dribeas    14 年前

    我会在课堂上使用typedef。原因是因为 std::vector ,大小类型为 std::size_t ,但如果以后将代码更改为使用大小类型不是 STD:SsieZiTt 重新定义typedef就足够了。

    使用该typedef不会公开实现的任何细节,实际上它有助于封装。typedef中的重要元素是本地名称,而不是定义为的名称。

    for ( mytype::size_type i = 0; i < myelement.size(); ++i )
    

    在上面的for循环中,用户代码不知道 size_type 是有符号的或无符号的类型,它只起作用。您可以更改实现,并且只要更新前一代码的typedef,就可以编译前一代码,而不会出现有符号/无符号的比较警告。typedef实际上有助于封装。

        3
  •  2
  •   anon    14 年前

    这些细节是什么?唯一暴露的是索引所需的大小(几乎可以肯定是大小)。添加typedef不会公开更多信息。

        4
  •  1
  •   Péter Török    14 年前

    所有大小类型基本上都是同一个标量类型,由于它是标量类型,因此它对于编译器是隐式可转换的。因此,使用 std::size_t , std::vector::size_type 或任何其他类似类型。

    提供一个 typedef 在你的班级里输入尺码。imo显示的typedef不会暴露太多的实现,因为客户机应该使用typedef,而不是 vector::size_type 直接。但是如果你愿意的话

    typedef std::size_t SIZE_T;
    

    对我来说,这看起来同样不错。

        5
  •  1
  •   Michael Aaron Safyan    14 年前

    如果您希望获得最高级别的封装,那么我将使用:

    private:
        typedef std::vector<A*> container_type;
        container_type _container;
    public:
        typedef container_type::const_iterator const_iterator;
    
        const_iterator begin()const{ return _container.begin(); }
        const_iterator end()const{ return _container.end(); }
    

    通过使用迭代器而不是大小类型,您可以在std::vector和std::list之间切换。但是,如果您的班级要求随机访问,那么我将选择:

    private:
        typedef std::vector<A*> container_type;
        container_type _container;
    public:
        typedef container_type::size_type size_type;
        A* operator[](size_type idx)const{ return _container[idx]; }
        size_type size()const{ return _container.size(); }
    

    如果类的用户不需要能够遍历内部容器的内容,那么我只需将typedef保持为私有,而不提供那些公共访问器函数。

        6
  •  0
  •   Jason Govig    14 年前

    如果你的班级已经在使用 std::vector<A*> 在其实现中,然后添加 typedef std::vector<A*>::size_type size_type 不会公开比已经公开的更多的细节。

    但是,如果您要进行完全封装,您需要一种技术,例如PIMPLIDOM或接口类(也称为协议类),完全隐藏它 标准::矢量<A*> 在实现中使用:

    之前:

    #include <vector>
    class A;
    class Foo {
    public:
        typedef std::vector<A*>::size_type size_type;
        size_type get_number_of_stuff() const;
    private:
        std::vector<A*> _stuff;
    };
    

    之后(使用PIMPL技术):

    class FooImpl;
    class Foo {
    public:
        typedef size_t size_type; // or just use size_t directly below
        size_type get_number_of_stuff() const;
    private:
        FooImpl* _impl;
    };
    

    fooimpl是在源文件中定义的,而不是在头文件中定义的,在实现细节中完全隐藏了向量的选择。因此,你不再需要 #include <vector> 在你的头文件中,它有几个好处:

    • 头文件的用户如果不使用vector,就不必(间接)包含它。这可以提高编译时性能,这在较大的代码库中很重要。
    • 如果您更改了实现(例如,to list),您就不会冒险破坏(错误地)依赖于您的 #包括<矢量> ,现在 #include <list> . 它发生了。