2010-04-05 86 views
2

採取這種簡單的代碼:在基礎中使用抽象期望它是派生類?

class A{ 
    public: 
    virtual void foo() = 0; 
    void x(){ foo(); } 
}; 
class B: public A{ foo(){ ... } }; 

main(){ 
    B b; 
    b.x(); 
} 

我要的是建立一個抽象類,將有會調用一個函數期待它在派生類中

的問題是,實現的功能我似乎無法完成這項工作,編譯器稱它無法編譯,因爲它無法找到引用(或類似的內容)到foo()以在基類的x()中執行。這可以工作嗎?任何人都可以給我一個這樣的例子嗎?

編輯:它似乎只是不工作時,「foo();」在A級(基礎級)的破壞者之內......
它讓我感到困惑。 = [

EDIT2:這有多有趣。我剛剛創建了一個callfoo(){foo(); }現在它編譯好了,但如果我試圖直接從基類A的析構函數中調用純抽象函數,它會給我錯誤......怪異。任何人都有這個想法嗎? O_o

對此有任何幫助嗎?

感謝,
喬納森

更新

它的工作的析構函數之外。現在我只是感到困惑。

嘗試把「富()」的A(基地)類的析構函數裏面,至少對我來說不是編譯...

任何幫助PLZ?

+0

在哪裏的問題? – 2010-04-05 00:14:46

+0

我會回到這裏接受任何關於這個問題的答案,如果我做錯了或不是,我正在使用gcc 4.3.2在vmware內的一個Linux機器中...感謝所有答案,到目前爲止,我喜歡這個網站非常多... – Jonathan 2010-04-05 00:45:56

+0

這是關於效率。只有在構建B對象的A部分時,才能創建和銷燬對象的最有效方法是對B本身一無所知(因此不能稱之爲方法)。 – baol 2010-04-05 00:54:45

回答

4

沒有什麼阻止你這樣做:

struct A { 
    virtual ~A() {} 
    virtual void f() = 0; 
    virtual void g() { f(); } 
}; 

struct B : A { 
    void f() { std::cout << "B::f()" << std::endl; } 
}; 

// ... 
A* a = new B; 
a->g(); // prints "B::f()" 

至於從析構函數(或構造函數)調用純虛函數:不要!它調用未定義的行爲。

第10.4節/ 6

成員函數可以從一個構造(或析構函數)一個抽象類的調用;對於從這樣的構造函數(或析構函數)創建(或銷燬)的對象,直接或間接地對純虛函數進行虛擬調用(10.3)的效​​果是未定義的。

+0

我喜歡虛擬析構觸摸:) – baol 2010-04-05 00:23:36

+0

我想創建一個類,必須有一個「DeleteItens」作爲一個抽象函數,將在基類的析構函數內調用。但我仍然得到未定義的參考= [ – Jonathan 2010-04-05 00:31:36

+0

@Jonathan:好像你問了一個錯誤的問題:) – baol 2010-04-05 00:35:01

1

它應該使用一些語法修改。

#include <iostream> 

class A { 
    public: 
    virtual ~A() {} 
    virtual void foo() = 0; 
    void x() { foo(); } 
}; 

class B: public A{ 
    void foo(){ std::cerr << "bingo!" << std::endl; } 
}; 

int main(){ 
    B b; 
    b.x(); 
    return 0; 
} 

$ g++ -Wall -Weffc++ derived.cc 
$ ./a.out 
bingo! 

這種技術是完全合法的。

1

好像你正在尋找的是的Template Method pattern.

您需要使用指針,以充分利用多態性(這樣就避免了消息的實現...x不是B類的()B的成員)

#include <iostream>                

class A{ 
    public: 
    virtual void foo() = 0; 
    virtual void x(){ foo(); } 
}; 
class B: public A{ 
     void foo(){ std::cout<<"this is b"<<std::endl; } 
}; 

int main(){ 
A* b= new B(); 
b->x(); 

return 0; 
} 
+1

x()是B的成員。它是從A公開繼承的。 – 2010-04-05 01:37:58

0

井理論作品一樣精緻,你應該加入雖然返回類型爲foo