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
  • 相关阅读:
    【转载】Android IntentService使用全面介绍及源码解析
    【转载】作为Android开发者,你真的熟悉Activity吗?
    【转载】从使用到原理学习Java线程池
    Linux 基础知识+常见命令
    Python中的字典合并
    Python的__hash__函数和__eq__函数
    C#中实现Hash应用
    深入理解python元类
    Docker搭建Gitlab服务器
    python的加密方式
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15638804.html
Copyright © 2011-2022 走看看