zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 38: Model "hasa" or "isimplementedintermsof" through composition.

    Item 32 explains that public inheritance means "is-a." Composition has a meaning, too. Actually, it has two meanings. Composition means either "has-a" or "is-implemented-in-terms-of."

    • Some objects in your programs correspond to things in the world you are modeling, e.g., people, vehicles, video frames, etc. Such objects are part of the application domain.
    • Other objects are purely implementation artifacts, e.g., buffers, mutexes, search trees, etc. These kinds of objects correspond to your software's implementation domain.

    When composition occurs between objects in the application domain, it expresses a has-a relationship.

    When it occurs in the implementation domain, it expresses an is-implemented-in-terms-of relationship.

    Suppose you need a template for classes representing fairly small sets of objects, i.e., collections without duplicates. your first instinct is to employ the standard library's set template. 

    Unfortunately, set implementations typically incur an overhead of three pointers per element. This is because sets are usually implemented as balanced search trees, something that allows them to guarantee logarithmic-time lookups, insertions, and erasures. 

    If  space is more important than speed for your application. It seems you’ll need to write your own template after all.

    In particular, you decide to have your nascent Set template inherit from list. That is, Set will inherit from list. After all, in your implementation, a Set object will in fact be a list object. You thus declare your Set template like this:

    template<typename T> // the wrong way to use list for Set
    class Set: public std::list<T> { ... };

    Because the relationship between these two classes isn't is-a, public inheritance is the wrong way to model that relationship. The right way is to realize that a Set object can be implemented in terms of a list object:

    template<class T>     // the right way to use list for Set
    class Set 
    {
    public:
        bool member(const T& item) const;
        void insert(const T& item);
        void remove(const T& item);
        std::size_t size() const;
    private:
        std::list<T> rep;     // representation for Set data 
    };

    Set's member functions can lean heavily on functionality already offered by list and other parts of the standard library, so the implementation is straightforward, as long as you're familiar with the basics of programming with the STL.

    template<typename T>
    bool Set<T>::member(const T& item) const
    {
        return std::find(rep.begin(), rep.end(), item) != rep.end();
    }
    
    template<typename T>
    void Set<T>::insert(const T& item)
    {
        if (!member(item)) 
            rep.push_back(item);
    }
    template<typename T>
    void Set<T>::remove(const T& item)
    { 
        typename std::list<T>::iterator it = // see Item 42 for info on "typename" here
        std::find(rep.begin(), rep.end(), item); 
        if (it != rep.end()) 
            rep.erase(it);
    }
    
    template<typename T>
    std::size_t Set<T>::size() const
    {
        return rep.size();
    }

    Things to Remember:

    • Composition has meanings completely different from that of public inheritance.
    • In the application domain, composition means has-a. In the implementation domain, it means is-implemented-in-terms-of
  • 相关阅读:
    时序图
    用例图
    欢迎界面(闪屏)
    WBS
    闲来听书
    软件团队的模式
    结对编程
    在个人项目中,找bug,审核代码.
    时序图
    部分功能的实现
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15638804.html
Copyright © 2011-2022 走看看