zoukankan      html  css  js  c++  java
  • 一个完整的使用成员函数指针的例子

    Screen.h

    #ifndef SCREEN_H
    #define SCREEN_H
    
    #include <string>
    
    class Screen {
    public:
        typedef std::string::size_type pos;
    
        // Action is a type that can point to a member function of Screen
        // that returns a reference to a Screen and takes no arguments
        using Action = Screen&(Screen::*)();
    
        // constructor: build screen of given size containing all blanks
        Screen(pos ht = 0, pos wd = 0): contents(ht * wd, ' '), cursor(0), 
                                        height(ht), width(wd) { }
        friend int main();
        // data is a static member that returns a pointer to member
        static const std::string Screen::*data() 
         { return &Screen::contents; }
    
        char get_cursor() const { return contents[cursor]; }
        char get() const { return contents[cursor]; }
        inline char get(pos ht, pos wd) const;
    private:
        std::string contents;
        pos cursor;
        pos height, width;
    
    public:
        // cursor movement functions 
        // beware: these functions don't check whether the operation is valid
        Screen& home() { cursor = 0; return *this; }
        Screen& forward() { ++cursor; return *this; }
        Screen& back() { --cursor; return *this; }
        Screen& up() { cursor += height; return *this; }
        Screen& down() {cursor -= height; return *this; }
    
        // specify which direction to move; enum see XREF(enums)
        enum Directions { HOME, FORWARD, BACK, UP, DOWN };
        Screen& move(Directions);
    private:
        static Action Menu[];      // function table
    };
    
    char Screen::get(pos r, pos c) const // declared as inline in the class
    {
        pos row = r * width;      // compute row location
        return contents[row + c]; // return character at the given column
    }
    
    inline
    Screen& Screen::move(Directions cm)
    {
        // run the element indexed by cm on this object
        return (this->*Menu[cm])(); // Menu[cm] points to a member function
    }
    
    #endif

    Screen.cpp

    #include "Screen.h"
    
    Screen::Action Screen::Menu[] = { &Screen::home,
                                      &Screen::forward,
                                      &Screen::back,
                                      &Screen::up,
                                      &Screen::down,
                                    };

    useScreen.cpp

    #include "Screen.h"
    
    #include <functional>
    using std::function; 
    
    #include <iostream>
    using std::cout; using std::endl;
    
    #include <string>
    using std::string;
    
    struct X {
        int foo(int i) { cout << "foo(" << i << ")" << endl; return i; }
    };
    
    void xfcn()
    {
        function<int (X*, int)> f;
        f = &X::foo;        // pointer to member
    
        X x;
        int v = f(&x, 5);
        cout << "v = " << v << endl;
    }
    
    int main ()
    {
        // pdata can point to a string member of a const (or nonconst) Screen
        const string Screen::*pdata;  // uninitialized
        pdata = &Screen::contents;    // points to the contents member
        auto pdata2 = &Screen::contents; // equivalent declaration
    
        // data() returns a pointer to the contents member of class Screen
        const string Screen::*pdata3 = Screen::data();
        
        // Screen objects
        Screen myScreen, *pScreen = &myScreen;
        const Screen cScreen, *pcScreen = &cScreen;
    
        // .* dereferences pdata to fetch the contents member 
        // from the object myScreen
        auto str = myScreen.*pdata;  // s is a string
        auto cstr = cScreen.*pdata;  // c is a const string
        
        // ->* dereferences pdata to fetch contents 
        // from the object to which pScreen points
        str = pScreen->*pdata;  
        
        // pmf is a pointer that can point to a Screen member function 
        // that takes no arguments, returns a char, and is const
        // that returns a char and takes no arguments
        auto pmf = &Screen::get_cursor;
        char (Screen::*pmf2)() const = &Screen::get; // same type as pmf
        
        pmf = &Screen::get; // which version of get deduced from type of pmf
        pmf2 = &Screen::get_cursor;
        
        Screen s;
        char c1 = s.get_cursor(); // gets character at the cursor directly
        char c2 = (s.*pmf2)();    // calls get_cursor indirectly through pmf2
        
        // call the function to which pmf points 
        // on the object to which pScreen points
        c1 = (pScreen->*pmf)();  
        
        // pmf3 points to the two-parameter version of get
        char (Screen::*pmf3)(Screen::pos, Screen::pos) const = &Screen::get;
        c1 = myScreen.get(0,0);     // call two-parameter version of get 
        c2 = (myScreen.*pmf3)(0,0); // equivalent call to get
        
        // Op is a type that can point to a member function of Screen 
        // that returns a char and takes two pos arguments
        using Op = char (Screen::*)(Screen::pos, Screen::pos) const;
        // equivalent declaration of Op using a typedef
        typedef char (Screen::*Op)(Screen::pos, Screen::pos) const;
    
        Op get = &Screen::get; // get points to the get member of Screen
        
        myScreen.move(Screen::HOME);  // invokes myScreen.home
        myScreen.move(Screen::DOWN);  // invokes myScreen.down
    
        // bind an object of type function to a pointer to member
        function<char (const Screen*)> f = &Screen::get_cursor;
    
        return 0;
    }
  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3759370.html
Copyright © 2011-2022 走看看