2012-03-19 58 views
16

我可以理解,可能有理由聲明一個實現的(而不是純粹的)虛擬函數private或protected。 Afaik,如果你聲明一個被實現的虛擬方法是受保護的,你的子類可以調用基類的方法(並且沒有其他人可以)。如果你聲明它是私有的,那麼只有基類可以調用虛擬方法的默認實現。私人和受保護的純虛函數之間是否有區別?

但是,對於純虛擬,沒有基礎實現......因此,它在功能上等同於將純虛擬聲明爲私有還是保護?受保護的純虛擬沒有意義,因爲您無法調用基類的相應方法。是否有任何情況下受保護的純虛擬有意義?

這裏有幾個類似的話題,但我找不到任何簡明回答我的問題的東西。

+0

你可以爲接口實現'friend'。 – Matthew 2012-03-19 02:00:32

+6

純虛方法可以具有主體,並且可以像base :: foo()那樣顯式調用它。 – iammilind 2012-03-19 02:02:13

回答

8

是否有任何情況下受保護的純虛擬使任何 感?

我認爲你是指私人在這裏(而不是保護),但我想我明白你的觀點。事實上,純虛擬的訪問類型可以在派生類中重寫。下面是可以幫助你看到的差別的例子的protected和private純虛:

class Parent 
{ 
    protected: virtual void foo() = 0; 
    private: virtual void bar() = 0; 
    public:   void test() { foo(); bar(); } 
}; 

class Child : public Parent 
{ 
    public: void test2() { foo(); /* bar(); // cannot be called here */ } 
}; 

class GrandChild : public Child 
{ 
    // access types here can be anything for this example 
    public: void foo() { cout << "foo" << endl; } 
    public: void bar() { cout << "bar" << endl; } 
}; 
+0

謝謝你的例子。只是澄清 - 一個私人的純虛擬永遠不會被其任何後代調用(但可以由他們實現,所以基類可以調用其後代的方法?) – Prismatic 2012-03-19 02:45:04

+0

否。在這個例子中,如果GrandChild調用'foo( )'在其另一個方法中,它會按預期進行編譯和工作,'GrandChild :: foo'將被調用。 – mfontanini 2012-03-19 02:58:57

+2

是的Pris,虛擬功能可以用不同的訪問類型覆蓋,這可能會打開它的可訪問性。 – LiquidAsh 2012-03-19 16:03:10

4

一是純虛函數可以實現!

#include <iostream> 

class Animal 
{ 
public: 
    void eat(void); 
protected: 
    virtual void doEat(void)=0; 
}; 
void Animal::eat(void) 
{ 
    doEat(); 
} 
void Animal::doEat(void) 
{ 
    std::cout << "animal" << std::endl; 
} 

class Tiger : public Animal 
{ 
private: 
    virtual void doEat(void) 
    { 
    Animal::doEat();//here is the difference between protected and private 
    std::cout << "tiger" << std::endl; 
    } 
}; 

int main(void) 
{ 
    Animal *p = new Tiger(); 
    p->eat(); 
    return 0; 
} 

其次,香草薩特解釋時使用「虛擬專用」或「虛擬保護」,你可以從這個article閱讀。我想,這也解釋了爲什麼我們這樣做不僅是我們可以在文章中說:」傾向於使虛擬功能成爲私有的,只有派生類需要調用虛函數的基本實現,才能使虛函數受到保護「,你的問題是關於純虛函數,我不太確定是否滿足這個原則。

相關問題