2011-01-12 89 views
8

下面是代碼樣本惹惱我:如何從派生類訪問基類中的受保護方法?

class Base { 
    protected: 
    virtual void foo() = 0; 
}; 

class Derived : public Base { 
    private: 
    Base *b; /* Initialized by constructor, not shown here 
       Intended to store a pointer on an instance of any derived class of Base */ 

    protected: 
    virtual void foo() { /* Some implementation */ }; 
    virtual void foo2() { 
     this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */ 
    } 
}; 

如何訪問到受保護的overrided功能?

感謝您的幫助。 :o)

+7

我不認爲你的實施是完全正確的。爲什麼你有一個Base的實例作爲成員變量? this-> b-> foo()會嘗試調用一個純粹的虛擬方法。 – GWW 2011-01-12 18:26:34

+1

這個程序不應該編譯。你不能實例化一個抽象類....除非`b`指向從`Base`派生的其他類的實例。 – 341008 2011-01-12 18:34:58

+0

我省略了精確性:Derived :: b屬性用於存儲基類 – 2011-01-13 10:44:15

回答

8

受保護的基類中的成員只能由當前對象訪問。
因此,您可以撥打this->foo(),但不允許撥打this->b->foo()。這與Derived是否提供foo的實施無關。

這個限制背後的原因是,否則它很容易繞過受保護的訪問。您只需創建一個類似Derived的課程,並且突然間您還可以訪問其他類別的部分課程(如OtherDerived),這些課程本應該是外界無法訪問的。

5

通常情況下,你可以使用Base::foo()來實現,它指的是當前實例的基類。但是,如果您的代碼需要按照您嘗試的方式進行操作,並且不允許,那麼您需要將foo()公開或派生爲Base的朋友。

0

您可以使用scope運算符(Base :: foo())顯式調用基函數。但是在這種情況下,Base類沒有定義foo(它是純虛擬的),所以當你說this->b->foo();時,實際上沒有函數可以執行,因爲b是指向Base而不是Derived的指針。

0

如何訪問受保護的 覆蓋功能?

---從哪裏來?

您只能通過繼承訪問受保護的成員(除了同一類的方法外)。例如說你有一個,它繼承自Derived,那麼Derived1的對象可以調用foo()

編輯:MSDN article受保護的訪問說明符。

1

這有點脆弱,但是您在這裏定義的類不會工作嗎?

virtual void foo2() { 
    reinterpret_cast<Derived *>(this->b)->foo(); 
} 

reinterpret_cast指向基礎對象的VTABLE,並通過此成員訪問器調用它。

2

一種解決方案是在Base中聲明一個將呼叫重定向到私有/受保護函數(示例中的foo)的靜態保護函數。

比方說:

class Base { 
protected: 
    static void call_foo(Base* base) { base->foo(); } 
private: 
    virtual void foo() = 0; 
}; 

class Derived : public Base { 
private: 
    Base* b; 
protected: 
    virtual void foo(){/* Some implementation */}; 
    virtual void foo2() 
    { 
     // b->foo(); // doesn't work 
     call_foo(b); // works 
    } 
}; 

通過這種方式,我們不打破封裝,因爲Base設計者可以做出明確的選擇,讓所有派生類調用foo對方,同時避免把foo進入公共界面或明確地將所有可能的Base的子類變爲朋友。

此外,無論foo是否爲虛擬,或者是私有的還是受保護的,此方法都可以工作。

Here是一個鏈接到上面的代碼的運行版本和here另一個版本的相同的想法多一點的業務邏輯。

相關問題