2016-04-16 79 views
1

我不知道應該如何進行模板專業化。這一次,不幸的是,谷歌和SO不能幫助我。在派生的模板類中專門設置一個基類的方法

對於基類:

class base 
{ 
public: 
    virtual ~base() = 0; 

    virtual int getInt() { throw std::invalid_argument(std::string(typeid(*this).name()) + " can't return int"); } 
}; 
base::~base() {} 

和派生類:

template<class T> 
class derived : public base 
{ 
public: 
    derived() {} 
    derived(T value) { mValue = value; } 

private: 
    T mValue; 
}; 

此代碼:

void proof(base* arg) 
{ 
    try 
    { 
     std::cout << arg->getInt(); 
    } 
    catch (std::exception& e) 
    { 
     std::cout << e.what(); 
    } 
    std::cout << "\n\n"; 
} 

int main() 
{ 
    base* a = new derived<int>(23); 
    base* b = new derived<std::string>("abc"); 

    proof(a); 
    proof(b); 

    delete a; 
    delete b; 

    return 0; 
} 

輸出,如果是不是已經明顯:

class derived<int> can't return int 

class derived<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > can't return int 

我應該如何進行派生的專門化,所以getInt()會返回mValue?例如:

template<> 
int derived<int>::getInt() { return mValue; } 

這是行不通的。我想調用arg-> getInt()和我調用arg-> getInt()時拋出的基類中的異常,我希望pe輸出爲23。 你能給我一個示例代碼嗎?謝謝。

+0

即默認構造函數看起來像一個可怕的想法!這是什麼意思*? –

+0

我想封裝一些數據類型,所以我可以製作多種數據類型的矢量。注意:int只是一個例子,我確實有另外一些類不包含primite類型。 –

回答

1

derived模板沒有getInt()方法。你不能專門化不存在的東西。

你必須專門化整個模板。試試這個:

template<> 
class derived<int> : public base 
{ 
public: 
    derived() {} 
    derived(int value) { mValue = value; } 
    int getInt() override { return mValue; } 
private: 
    T mValue; 
}; 
+0

如果這是唯一的解決方案,那麼我將不得不一遍又一遍地爲封裝做類。這正是我不想做的事:寫同一班10次,但使用不同的數據類型。感謝您的幫助。你確定這是唯一的方法嗎? –

+0

是的,這就是專業化在C++中的工作原理。我相信還有其他設計類層次結構的方法可以以不同的方式使用專業化。例如,您可以創建「template class not_really_derived:public base {};」,專門爲您的getInt()專門設計「not_really_derived 」,然後派生子類not_really_derived 而不是基礎,沒有專門化。 –

1

你可以專門的模板,int

template <> class derived<int> : public base 
{ 
public: 
    derived(int value) : mValue(value) {} 

    int getInt() override { return mValue; } 

private: 
    int mValue; 
}; 
+0

謝謝你幫助我。但是,不是另一種解決方案,所以我可以只專注於該功能? –

+0

@AndreiAndrey:你總是可以通過中間輔助基類將這個模式考慮進去,所以你不必重複任何通用的代碼。這只是一個蛋糕的成分,你仍然必須帶來所有其他的。 –

+0

去找雞,所以我會得到雞蛋。謝謝。 –