1. 程式人生 > >Static函式訪問非Static函式

Static函式訪問非Static函式

https://www.cnblogs.com/rickyk/p/4238380.html

方法1、

靜態函式的形參表裡加上例項的地址:

class A
{
public:
    static void test(A *a)
    {
        a->m_a += 1;
    }
    void hello()
    {
    }
private:
    static int m_static A;
    int m_a
};

這樣在你回撥函式的時候,你可以通過這個來讓本身不能訪問成員非靜態變數的靜態函式(太拗口)來訪問非靜態成員變數。

方法2、

其實這個方法在GLIB中用的很多,就是放上全域性變數地址:

A g_a;

class A
{
public:
    static void test()
    {
        g_a.m_a += 1;
    }
    void hello()
    {
    }
private:
    static int m_staticA;
    int m_a
};

這種方法我們瞭解就好,全域性變數我們並不推薦。

方法3:

大家都知道靜態成員函式不能訪問非靜態成員,但別忘了,他們可以訪問靜態成員,也就是說,如果我們的這個類是個單例,我們完全可以在建立的時候把this指標賦值給那個靜態成員,然後在靜態成員函式內部就可以放心大膽的使用了。

如果保證類是單例?下面執行會出問題!

class A
{
public:
    A()
    {
        m_gA = this;
    }
    static void test()
    {
        m_gA.m_a += 1;
    }
    void hello()
    {
    }
private:
    static int m_staticA;
    static A *m_gA;
    int m_a
};

方法4:

和方法一比較像,但他的方向思想更多的是針對記憶體塊這個概念,意思就是在靜態函式的形參比加上一個void *的記憶體首地址,然後在內部做轉換

class A
{
public:
    static void test(void *pData)
    {
        A *a = (A *)pData;
        a->m_a += 1;
    }
    void hello()
    {
    }
private:
    static int m_staticA;
    int m_a
};

A a;
test(&a);

如上,我整理了4種方法,當然方法還有很多,其實繞了這麼大遠路,我們的希望就是不破壞回撥函式整潔的函式介面(加上自己的例項指標)而做的妥協,如果你更喜歡通過改變介面或者通過用Java類似的interface方式來實現,那也沒有問題,這裡主要就是提供給大家一個思路,C++確實很靈活,我們要用好這把雙刃劍 : )