2012-01-31 46 views
0

如果不抽象,則調用基類方法。如果不抽象,調用基類方法

class WithAbstMethod { 
public: 
    virtual void do() = 0; 
} 

class WithImplMethod : public WithAbstMethod { 
public: 
    virtual void do() { 
     // do something 
    } 
} 

template<typename BaseT> 
class DerivedClass : BaseT { 
public: 
    virtual void do() { 
     BaseT::do(); // here is a question. How to modify code, so that do() is called if it is not abstract? 
     // do something 
    } 
} 

void main() { 
    DerivedClass<WithAbstMethod> d1; 
    d1.do(); // only DerivedClass::do() should be called 
    DerivedClass<WithImplMethod> d2; 
    d2.do(); // both WithImplMethod::do() and DerivedClass::do() should be called 
} 

是否有可能做到這一點在編譯時使用模板沒有太多的代碼(實例DerivedClass :: DO()方法巴塞特:: DO()調用並且不依賴於巴塞特型)? 顯然,在WithAbstMethod類中提供實現不是一個選項。上面的代碼是僞代碼,因此可能包含小錯誤。

+3

請注意'do'是C++中的保留字:) – 2012-01-31 23:49:40

回答

3

實際上,提供WithAbstMethod::do()的實現可能是一個選項。抽象函數被允許有一個實現。

void WithAbstMethod::do() 
{ 
    // do nothing... 
} 
+0

我不太明白你的意思。這種方法應該是設計抽象的。所以我想在這樣的代碼中編譯時錯誤:void main(){WithAbstMethod a1; } – cos 2012-01-31 23:57:42

+1

那麼,你應該已經爲'void main()'得到了一個編譯時錯誤。除此之外,如果'WithAbstMethod :: do()'是抽象的,如果你實現它,你仍然會遇到編譯時錯誤!啊 - 你沒有注意到你可以實現抽象成員,我想:你可以! 'struct A {void B()= 0; }; void A :: B(){}'這是一個具有實現抽象函數'A :: B()'的抽象類'A'。這可以例如對你的情況有用。 – 2012-02-01 00:05:59

+1

編譯器不會讓你實例化一個抽象類(換句話說,在函數聲明中保留'= 0')。但是,您仍然可以獲得派生類可以調用的抽象函數的實現。對於可以很好且容易地工作的'void'函數;它可能不適合,如果你有抽象函數將不得不返回的東西,並沒有明智的「默認」。 – 2012-02-01 00:06:58