2015-07-03 77 views
2

考慮下面的代碼段:多繼承與模板接口

template.h

template<typename T> 
class templ{ 
public: 
    virtual const int virtualMethod(const T *const) const = 0; 
} 

Base.h

#include "template.h" 

class Der1; 
class Der2; 

    class Base : 
     public templ<Base>, 
     public templ<Der1>, 
     public templ<Der2>{ 
    public: 
     virtual ~Base(){} 
    }; 

Der1.h

#include "Base.h" 

class Der1 : public Base { 
public: 
    virtual const int virtualMethod(const Base *const) const override; 
    virtual const int virtualMethod(const Der1 *const) const override; 
    virtual const int virtualMethod(const Der2 *const) const override; 
}; 

Der1。 cpp

#include "Der1.h" 

const int Der1::virtualMethod(const Base *const sth) const{ 
    return sth->templ<Der1>::virtualMethod(this);//does not work 
    //how to fix it? 
} 

const int Der1::virtualMethod(const Der1 *const sth) const{ 
    //do sth 
} 

const int Der1::virtualMethod(const Der2 *const sth) const{ 
    //do sth 
} 

類Der2也從Base繼承並實現了這三個函數。

對於這個代碼編譯器給我這些消息:

  1. 'TEMPL' 不明確「候選人有:TEMPL()TEMPL(常量 TEMPL &)TEMPL()TEMPL(常量TEMPL &)TEMPL() TEMPL(常量TEMPL &)'
  2. 函數 'virtualMethod' 不能被解析
  3. 命名空間的成員函數 'virtualMethod' 不能被解決。
  4. 類型'Der1'無法解析。
  5. 未定義參考 `TEMPL :: virtualMethod(Der1常量*)常量」

一般情況下,代碼的想法是實現double類型調度。雖然我認爲我知道是什麼原因造成問題,但我不知道如何解決問題。所以,也許你可以幫助我。

+0

你可能想用[CRTP(https://en.wikipedia.org/ wiki/Curiously_recurring_template_pattern)而不是嵌入式抽象基類。 –

+0

請不要混合靜態多態(模板)和動態多態(虛擬),除非你知道你在做什麼。 –

+0

此外,在定義接口時,您應該使用虛擬繼承(避免多個基類) –

回答

0

我有點困惑什麼是你的意圖......

但怎麼樣:

const int Der1::virtualMethod(const Base *sth) const { 
    return dynamic_cast<const templ<Der1> *>(sth)->virtualMethod(this); 
} 
+0

這絕對是**不**我所尋找的。我寫的代碼的主要目的是避免dynamic_cast和RTTI。不要提及你的代碼是危險的,因爲沒有檢查'nullptr'的動態轉換結果。 – bartop

+0

當然,你應該檢查轉換結果,但我忽略這一點,因爲它不是大部分解決方案,我認爲在這種情況下它不是必需的,因爲轉換總是會是正的(除非sth = nullptr,它沒有在你的代碼也是)。 – yzz