2013-01-05 163 views
1

我有抽象類A覆蓋構造函數C++

class A{ 
public: 
    A(dim) : dim_(dim); 
private: 
    int dim_; 
} 

和B類

class B : public A{ 
public: 
    B(int dim); 
} 

,我需要爲B類,只有當朦朧> 1,並拋出斷言,否則其工作的構造。

在這種情況下

B::B(int dim) : A(dim){ 
    assert(dim > 1); 
} 

它的工作原理,但它不是很好的解決方案,我認爲,這是因爲A類的實例被創建和刪除

比我做A類初始化方法:

class A{ 
public: 
    void init(int dim){ 
    dim_ = dim; 
    } 
    A(int dim){ 
    init(dim); 
    } 
private: 
    int dim_; 
} 

,改變B類的構造函數:

class B : public A { 
public: 
    B(int dim){ 
    assert(dim > 1); 
    init(dim); 
    } 
} 

,但它不工作。我的問題有沒有可能的解決方案?

+1

class'A' is not _abstract _... –

+0

不知何故,我覺得依賴'暗'你ctor的感覺是錯誤的方法。 –

回答

5

我想你可以寫一個小myint類,可以確保您通過int總是大於1

struct myint 
{ 
    int data; 
    myint(int i) : data(i) { assert(data > 1); } 
}; 

現在,在您的課堂上使用它:

class B : public A{ 
public: 
    B(myint dim) //this can still take int, due to implicit conversion! 
    : A(dim.data) { } 
} 

注意您仍然可以構造B傳遞int,因爲它會隱式轉換爲myint,並且在轉換髮生(隱式)時,它會將te st 斷言,如果成功,只有這樣你才能夠將dim.data傳遞給基類A。如果聲明失敗,那麼程序將在進入基類構造函數之前中止(不在派生類中初始化任何內容)。


你甚至可以概括它:

//Summary : gint<N> makes sure that data > N 
template<int N> 
struct gint //call it greater int 
{ 
    int data; 
    gint(int i) : data(i) { assert(data > N); } //Use N here! 
}; 

現在,在您的課堂上使用它:

class B : public A{ 
public: 
    B(gint<1> dim) //the template argument 1 makes sure that dim.data > 1 
    : A(dim.data) { } 
} 

如果您需要另一個類,例如:

class Xyz : public A{ 
public: 
    B(gint<10> dim) //gint<10> makes sure that dim.data > 10 
    : A(dim.data) { } 
} 

很酷,是不是?

+1

我曾見過公司有政策總是將單參數構造函數聲明爲'explicit',我相信這是有充分理由的。不過我相信你對這個問題的解決方案非常酷。 –

+0

@izomorphius:是的,他們可能有很好的理由。但它並不總是好的。 'std :: string'有*非顯式*單參數構造函數,我認爲這是非顯式的,這是有原因的。 – Nawaz

+1

這是很酷的解決方案。在蘇聯俄羅斯,我們稱這樣的解決方案爲'Kostyl'(意思是「歪指甲」,根據谷歌翻譯) – user1761982

0

如果你想讓你的第二選項工作,你將不得不添加一個空的構造函數A。然而,這不會對你有太大的幫助,因爲A對象是在你輸入B的構造函數之前創建的,因此無論你有一個空構造函數還是一個接受int類型對象的構造函數,你總是會構造一個類型爲A的對象。

如果A與您在本示例中顯示的一樣簡單,那麼即使對於無效的暗淡點,構建它也不是什麼大問題。如果它更復雜,我建議你爲A創建一個空的構造器,它儘可能地初始化爲A的一小部分,然後用一個方法來做更復雜的事情。

+0

並使空構造函數(它不調用init())保護,以便僅在B(int ); – Necto