[C++]pointer-like classesとfunction-like classes

3756 ワード

1.pointer-like classはポインタのようなクラスを意味し、1つのクラスが撮像ポインタとして設計されているようにポインタとして使用できることを意味する.スマートポインタと反復器の2つの一般的なポインタクラスについて説明します.
a.スマートポインタ
namespace ll {
    template
    class shared_ptr
    {
    public:
        T& operator* () const {
            return *px;    //         
        }
        T* operator->() const {
            return px;
        }
        shared_ptr(T* p): px(p) {}
    private:
        T *px;    
    };
}

struct Foo
{
    void method() {
        cout << "method" << endl;
    }
};

ll::shared_ptr sp(new Foo);  //        Foo       
Foo f(*sp);  //      Foo  ,       sp            
f.method();  //     f      
sp->method();  //       

上記のコードは、スマートポインタspを示し、メンバー関数を->オペレータによって呼び出す.sp->method();オペレータ関数operator->()constが最初に呼び出され、スマートポインタ内部の実際のポインタpxが得られ、pxを介してmethod関数(px->method()が呼び出されます.ここで疑問なのは、sp->オペレータ関数operator->()を呼び出すことで->シンボルが消費され、px->method()の->はどのように来たのかということです.C++は、->オペレータを呼び出すと->オペレータは消費されずに機能し続けることを規定しており、spmethod();sp->method()に等しい.
b.反復器
namespace ll {
    template
    struct __list_node {
        void *prev;
        void *next;
        T data;
    };

    template
    struct __list_iterator {
        typedef __list_iterator self;
        typedef Ptr pointer;
        typedef Ref reference;
        typedef __list_node* link_type;
        link_type node;

        reference operator*() const {
            return (*node).data;
        }
        pointer operator->() const {
            return &(operator*());
        }
        self& operator++() {
            node = (link_type)((*node).next);
            return *this;
        }
        self& operator--() {
            node = (link_type)((*node).prev);
            return *this;
        }  
    };
}



//         
struct Foo
{
    void method() {
        cout << "method" << endl;
    }
};

ll::__list_iterator iter;
*iter;  //     Foo  
iter->method();  //      Foo::method(),   (*iter).method(),    (&(*iter))->method()


まず、私たちは1つの_list_iterator反復器iter、*オペレータでFooオブジェクト、iter->method()を得ることができます.するとFoo::method()が呼び出され、以下のように解釈されます.
  iter->method();まずoperator->()const関数が呼び出されます.operator->()constではoperator*()も呼び出されます.まずdataを取得してからアドレスを取ります.すべてのoperator->()constはdataのアドレスを返します.前例ではFooオブジェクトのアドレスです.これにより、->オペレータでFoo::method()を呼び出すことができます.
注意:->記号の意味、メンバー抽出、例えばA->B、Aはクラス、構造、連合を指すポインタであり、A->BはAのメンバーBを抽出することを指す.
 
2.function-like classesシミュレーション関数のクラス
シミュレーション関数のクラスの特徴は、次の例のようにオペレータoperator()を再ロードすることです.

template 
struct pair
{
  T1 first;
  T2 second; //first second       
  pair() : first(T1()), second(T2()) {}
  pair(const T1& a, const T2& b)
  : first(T1()), second(T2())
......
};



template
struct identity : public unary_function
{
  const T&
  operator() (const T& x) const { return x; }
};
 
template
struct select1st : public unary_function
{
  const typename Pair::first_type&
  operator() (const Pair& x) const { return x.first; }
};
 
template
struct select2nd : public unary_function
{
  const typename Pair::second_type&
  operator() (const Pair& x) const { return x.second; }
};

 
参考ブログ:
https://blog.csdn.net/lihao21/article/details/50668271
https://blog.csdn.net/SUSU0203/article/details/80478029