2011-07-10 33 views
4

假設這個結構是否有意義從一個抽象(純虛擬)類私下繼承?

struct InterfaceForFoo 
{ 
    virtual void GetItDone() = 0; 
}; 


class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo 
{ 

    public: 
    void GetItDone() { /*do the thing already*/ }; 
}; 

現在,我想知道如果從這樣的接口繼承私下做任何有用的方案。

回答

5

呵呵,這裏的每個人都說「不」。我說「是的,它確實有意義。」

class VirtualBase { 
public: 
    virtual void vmethod() = 0; 
    // If "global" is an instance of Concrete, then you can still access 
    // VirtualBase's public members, even though they're private members for Concrete 
    static VirtualBase *global; 
}; 

// This can also access all of VirtualBase's public members, 
// even if an instance of Concrete is passed in, 
void someComplicatedFunction(VirtualBase &obj, ...); 

class Concrete : private VirtualBase { 
private: 
    virtual void vmethod(); 
public: 
    void cmethod() { 
     // This assignment can only be done by Concrete or friends of Concrete 
     VirtualBase::global = this; 
     // This can also only be done by Concrete and friends 
     someComplicatedFunction(*this); 
    } 
}; 

製作繼承private並不意味着你不能從類外部訪問的VirtualBase成員,它只是意味着你無法通過參考訪問這些成員Concrete。但是,Concrete及其朋友可以將Concrete的實例投射到VirtualBase,然後任何人都可以訪問公共成員。簡單地說,

Concrete *obj = new Concrete; 
obj->vmethod(); // error, vmethod is private 

VirtualBase *obj = VirtualBase::global; 
obj->vmethod(); // OK, even if "obj" is really an instance of Concrete 
+0

我不說「不」。看到我的答案。 :) – iammilind

-1

不是。如果你需要一個功能,你可以實現它。強制一個不能被其他類使用的函數是沒有意義的。

爲什麼你會從一個接口私下繼承,我不知道;那種打破界面的目的。

如果它不是一個接口,而是一個類,它是有道理的:

class A { 
    virtual void foo() = 0; 

    void bar() { 
     foo(); 
    } 
}; 

class B : private A { 
    virtual void foo() { 

    } 
}; 
0

嗯?不,這絕對沒有意義,因爲您提供界面的原因是您希望其他人通過該界面使用您的班級。如果他們不知道你實施它,那該怎麼辦?

#include <vector> 

class Fooable{ 
public: 
    virtual void foo() = 0; 
}; 

class DoesFoo 
    : private Fooable 
{ 
    void foo(); 
}; 

int main(){ 
    std::vector<Fooable*> vf; 
    vf.push_back(new DoesFoo()); // nope, doesn't work 
    vf[0]->foo(); 
} 

上面的例子不工作,因爲外界並不知道DoesFooFooable,因此你不能new它的一個實例,並將其分配給Fooable*

+0

我不認爲我會得到一個答案,但... ... @匿名downvoter,謹慎解釋? – Xeo

1

在面向對象方面,沒有使用這種private繼承的抽象class

但是,如果你想強制你的孩子class必須得到某些方法,那麼你可以使用它。例如:

struct implement_size 
{ 
    virtual size_t size() = 0; 
}; 

class MyVector : private implement_size 
{ 
public: 
    size_t size() { ... } // mandatory to implement size() 
} 

class MyString : private implement_size 
{ 
public: 
    size_t size() { ... } // mandatory to implement size() 
}; 

所以,它只是幫助維持個人編碼規則。這個例子的消息是,繼承不僅僅意味着面向對象的目的。你甚至可以use inheritance for stopping inheritance chain(類似Java final)。

+0

「_object oriented aspect_」是什麼? – curiousguy

+0

@curiousguy,=> OO術語/哲學。 – iammilind

+0

如果我看到僅使用純虛函數來強制執行該方法,我會抱怨。 「MyVector」和「MyString」共享一個接口('Container'?)或不共享。如果他們不這樣做,那麼創建一個虛擬接口就沒有意義了,而當size()不是多餘地使用時,更不用說它是一個虛函數。 –

1

問題是爲什麼基本類只有純虛擬方法才重要?

這兩件事情幾乎無關。私有意味着它是你的類的實現細節,而不是公共接口的一部分,但你可能想要實現一個接口作爲實現細節。考慮你編寫了一個類,並決定通過需要實現接口的庫來實現該功能。這是一個實現細節,沒有必要僅僅因爲接口只具有純虛函數而使繼承公開