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
  • 相关阅读:
    Windows环境下Unicode编程总结
    我的CS脚本autoexec.cfg
    完成端口与高性能服务器程序开发[引用]
    调用未知DLL中的导出函数
    兼容Vista 赛门铁克公测新杀毒软件
    I Love You的真正含义
    码根码
    木马经典十大藏身地点大搜查
    Windows调试器及不同平台符号包下载地址(收集)
    “千般路”与“磨豆腐”
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15638804.html
Copyright © 2011-2022 走看看