2011-04-16 201 views
5

試圖創建一個驅動程序類型類,其中,下面的Base是在實例化時傳遞類型的驅動程序。在這種情況下,類型2用於構造正確的派生對象。從基類實例化派生對象

我的編譯器在「Class Base」行上拋出了一個Declaration語法錯誤。

我的最終目標是能夠做到這一點:

Base *B; 

    B = new Base(2); 
    if(B) 
    { 
     B->DoStuff(); 
     B->DoMoreStuff(); 
     delete B; 
    } 

這裏是我的代碼將無法編譯...

class Base 
{ 
public: 

    Base(int h); 
    virtual ~Base(); 

private: 
    int hType; 
    Base *hHandle; 
}; 


class Derived1 : public Base 
{ 
public: 
    Derived1(); 
    virtual ~Derived1(); 

}; 

class Derived2 : public Base 
{ 
public: 
    Derived2(); 
    virtual ~Derived2(); 

}; 

Base::Base(int h) 
{ 
    hType = h; 

    switch(h) 
    { 
     case 1: 
      hHandle = new Derived1; 
     break; 

     case 2: 
      hHandle = new Derived2; 
     break; 

    } 
} 


Derived1::Derived1():Base(1) 
{ 
    printf("\nDerived1 Initialized\n\n"); 
} 

Derived2::Derived2():Base(2) 
{ 
    printf("\nDerived2 Initialized\n\n"); 
} 

下面是更新後的代碼,以顯示完整的源代碼。我想我現在明白爲什麼它不會編譯。正如下面指出的,我有一個無限循環呼叫'新'

#include <stdio.h> 

class Base 
{ 
public: 

    Base(); 
    Base(int h); 
    Create (int h); 
    virtual ~Base(); 

private: 
    int hType; 
    Base *hHandle; 
}; 


class Derived1 : public Base 
{ 
public: 
    Derived1(); 
    virtual ~Derived1(); 

}; 

class Derived2 : public Base 
{ 
public: 
    Derived2(); 
    virtual ~Derived2(); 

}; 

Base::Base() 
{ 

} 

Base::Base(int h) 
{ 
    Create(h); 
} 

Base::Create(int h) 
{ 
    hType = h; 

    switch(h) 
    { 
     case 1: 
      hHandle = new Derived1; 
     break; 

     case 2: 
      hHandle = new Derived2; 
     break; 

    } 
} 

Derived1::Derived1() 
{ 
    printf("\nDerived1 Initialized\n\n"); 
} 

Derived2::Derived2() 
{ 
    printf("\nDerived2 Initialized\n\n"); 
} 
+0

錯誤的文字是什麼?如果它指的是你的代碼片段的第一行,那不*看*錯誤。 – ssube 2011-04-16 03:19:49

+2

運行時怎麼樣?當你創建一個Base(1)時,構造函數創建一個新的Derived,它調用它的基類Base(1),它創建一個新的Derived,它調用它的基類... – 2011-04-16 10:48:47

+0

@Eric:請使用'std :: unique_ptr','boost :: scoped_ptr'或'std :: auto_ptr'(後者更糟糕)。你的玩具樣品有內存泄漏:/ – 2011-04-16 14:18:36

回答

2

它看起來像你試圖做class factory

我建議你在Base中有一個返回Derived1或Derived2的靜態方法。

class Base 
{ 
public: 
    static Base* Create(int); 
    virtual void DoStuff() = 0; 
} 

class Derived1 : public Base 
{ 
    Derived1() 
    { 
     printf("\nDerived1 Initialized\n\n"); 
    } 

    virtual void DoStuff() 
    { 
    } 
} 

class Derived2 : public Base 
{ 
    Derived2() 
    { 
     printf("\nDerived2 Initialized\n\n"); 
    } 

    virtual void DoStuff() 
    { 
    } 
} 

Base* Base::Create(int n) 
{ 
    if (n==1) 
     return new Derived1(); 
    else if (n==2) 
     return new Derived2(); 
    else 
     return nullptr; 
} 

void main() 
{ 
    Base* B = Base::Create(2); 
    if(B) 
    { 
     B->DoStuff(); 
     delete B; 
    } 
} 
+0

這很有趣,我可以閱讀/理解這一點,但我仍然在摸索爲什麼我的代碼不能編譯?這最終不能回答我的問題。我不希望調用者必須知道Base :: Create的細節。如果可能的話,我希望調用者只需調用新的Base(類型)? – Eric 2011-04-16 02:58:17

+0

首先,你的代碼試圖調用它沒有聲明的函數,你必須在hHandle中調用它們的代理方法。其次,最值得注意的是不會被編譯器捕獲,Derived1的創建將調用Base構造函數在無限循環中創建另一個Derived1實例。 – 2011-04-16 04:33:56

+0

忽略最後一個註釋的第一部分...如果Base Base有語法錯誤,可能是由於上面缺少分號,可能是包含文件。我認爲這條線沒有錯。你能否提供編譯器的完整錯誤? – 2011-04-16 04:42:01

相關問題