2011-09-05 107 views
16

我有一個程序,我需要在dll和一些應用程序代碼之間共享一個基類。然後我有兩個不同的派生類,一個在主應用程序中的一個。其中每一個都有一些靜態成員函數,它們對nase類中的數據進行操作。 (它們需要是靜態的,因爲在別處用作函數指針)。以最簡單的形式,我的問題如下所示。我可以從派生類中的靜態函數訪問基類保護成員嗎?

class Base { 
protected: 
    int var ; 
}; 

class Derived : public Base { 
    static bool Process(Base *pBase) { 
    pBase->var = 2; 
    return true; 
    } 
}; 

我的編譯器抱怨說我不能訪問受保護的pBase成員,儘管Derived已經保護了對Base的訪問。有沒有辦法解決這個問題,還是我誤解了一些東西? 我可以使基本變量公開,但這將是不好的,因爲在我的實際情況下,這些是分配內存和信號量的一大塊來保護它的多線程。

幫助?

+1

[Accessing parent's protected variables](http://stackoverflow.com/questions/4829518/accessing-parents-protected-variables)可能出現重複。這並不是關於函數是否是'static',而是因爲通過其訪問基本成員的參數不是Derived類型。 –

+0

靜態函數的參數必須是基類以符合函數指針的調用要求。也許我可以用動態轉換來解決這個問題 –

+1

如果你可以控制這個函數,只有指向'Base'對象的指針才能被調用,它們是'Derived'對象的基類子對象,你可以使用'static_cast'從函數體中的'Base *'到'Derived *'。否則,你將不得不成爲'Base'的'朋友',或者你可以改變'var'爲公開的。如果你不能做任何這些,那麼你就卡住了。 –

回答

10

一般情況下(無論函數是否爲靜態函數),派生類的成員函數只能訪問其類型對象的受保護基類成員函數 。如果靜態類型不是派生類 (或從其派生的類)的靜態類型,它不能訪問受保護的 成員。所以:

class Base { 
protected: 
    int var; 
} ; 

class Derived : public Base { 
    static void f1(Derived* pDerived) 
    { 
     pDerived->var = 2; // legal, access through Derived... 
    } 
    static bool Process(Base *pBase) 
    { 
     pBase->var = 2 ; // illegal, access not through Derived... 
    } 
} ; 
+0

所以我想我的靜態函數用於函數指針,參數需要是基類,我應該能夠動態地轉換爲派生類。 –

+1

如果基類至少有一個虛函數,是的。 (或者你可以修改函數來獲取'Derived *',並將'dynamic_cast'留給客戶端。) –

0

訪問符適用於Derived類手柄(參考/指針/對象),而不是Derived類本身的方法。即使該方法不是static,也會以相同的錯誤結束。因爲您未使用派生句柄訪問varDemo

正確的方法是提供一個setter方法:

class Base { 
protected: 
    int var ; 
public: 
    void setVar(const int v) { var = v; } // <--- add this method 
}; 

注:有一個出更多的方式,但我不知道這是否是優雅。

(static_cast<Derived*>(pBase))->var = 2; 
+0

不幸的是,在我的真實類中,基類中的數據實際上是一些內存塊和一大堆信號量用於多線程訪問。對於信號量和內存塊使用getter和setter似乎非常麻煩,因爲基礎中可能有10-15個變量。 –

相關問題