2012-07-09 49 views
-3
#define classAnum 2; 
#define classBnum 3; 

class Base 
{ 
    virtual int open()=0; 
    virtual int close()=0; 
} 
class A:public Base 
{ 
virtual int open(); 
virtual int close(); 
}; 

class B:public Base 
{ 
virtual int open(); 
virtual int close(); 
} 

int main() 
{ 
    A classA[classAnum]; 
    B classB[classBnum]; 

openAnyClass(1); 
CloseAnyClass(2); 
} 

我想實現這樣的功能。C++調用駐留在多個類中的函數

openAnyClass(1); 
CloseAnyClass(2); 

這兩個函數應該能夠從任何類A和B.調用open()和close()

openAnyClass(1)將呼叫在第一對象的open()函數classA或classB的數組。

open() - >將在類A和類B中具有不同的實現,並且classA中的open()可能會從多個客戶端調用,沒有。的客戶是#定義的。

一次只有一個open()來自任何classA或classB被調用。我不想有多個相同代碼的副本。

只有一個函數,我想要打開()任何類A和任何客戶端。例如:在下面的語句中,我想調用client1的class A的open()方法。 openAnyClass(int)的參數表示客戶端ID。這也意味着classB[1].open();

'openAnyClass(1) = classA[1].open();' 

這樣做的最好方法是什麼?

+0

不可能有不同的相同方法的實現 - 多重open()是什麼意思?如果您在調用openAnyClass時將指針/引用傳遞給Base(從A類或B類的實例上傳),那麼您將能夠在此指針/引用上調用open或close並「自動」地調用正確的方法根據「真實」類調用(A :: open()或B :: open()) – 2012-07-09 10:05:55

+2

@ user1511617「openAnyClass()」和「closeAnyClass()」的參數是什麼意思? – 2012-07-09 10:13:04

+0

所以classA是A的數組,classB的數組也是一樣。並調用openAnyClass(1),意味着在A的所有實例上調用open(),closeAnyClass()表示在classB的所有實例上調用close()。好的,如果是這樣的話,這個問題確實很複雜。 – 2012-07-09 10:24:27

回答

1

這就是你得到一個命令基類的原因;這樣你可以擁有一個指向類的指針或引用,並通過虛函數在派生類中調用open/close方法。

所以,如果你有

Base *generic_class_pointer = new class A(); 

generic_class_pointer->open(); 

的generic_class_pointer-> open()的調用將在A級定義的代碼

什麼你想與存儲對象兩個數組,一個做對於類A和類B的一個並不是必需的,您可以擁有一個指向Base類的類並通過它訪問的單個數組。

原始代碼並不是一個真正的工作方式,最好通過列表來完成(例如,stl::vector)。

Base* class_storage[StorageSize]; 

int openAnyClass(int id) 
{ 
    if (id < 0 || id >= StorageSize || class_storage[id] == 0) 
     return 0; // or other error indication 
    else 
     return class_storage[id]->open(); 
} 
int CloseAnyClass(int id) 
{ 
    if (id < 0 || id >= StorageSize || class_storage[id] == 0) 
     return 0; // or other error indication 
    else 
     return class_storage[id]->close(); 
} 


int main() 
{ 
    memset(class_storage,0,sizeof(class_storage)); 

    class_storage[1] = new A(); 
    class_storage[2] = new B(); 

    openAnyClass(1); 
    CloseAnyClass(2); 
} 

上面的代碼是不是一個完整的解決方案,例如原來沒有虛析構函數這是一個很好的做法,始終使用 - 的情況下,派生類中需要做清理工作。

另外,刪除分配到class_storage中的對象在我的示例上未被釋放。這在全球範圍內並不重要,因爲它們在退出時將被釋放,但大多數情況下,您需要管理通過new()獲取的所有內容,否則會導致內存泄漏。

+0

memset調用是多餘的,因爲全局數組的元素會自動進行默認初始化。儘管如此,'Base class_storage [StorageSize] = {0};'無論如何將會更好地向新手呈現。 – mloskot 2012-07-09 10:47:38

+1

如果您需要用'new'分配對象,請記得刪除它們,或使用智能指針來管理它們。他們幾乎肯定會需要虛擬析構函數。 – 2012-07-09 11:16:45

+0

openAnyClass(1)將調用classA或classB數組中第一個對象的open()函數。 – Fancier 2012-07-09 13:12:51

0

so classA是A的數組,classB的數組是一樣的。並調用openAnyClass(1),意味着在A的所有實例上調用open(),closeAnyClass()表示在classB的所有實例上調用close()。以及如果是這樣的話,這個問題是非常複雜的制定

反正有沒有不知道現成的方法來做到這一點。你必須遍歷數組的所有元素並調用open()或close()。或者您可以使用升壓的foreach http://www.boost.org/doc/libs/1_39_0/doc/html/foreach.html 或實現自己的foreach方法

0

如果我理解你的問題正確的話,你要調用一個純虛函數的不同實現。假設你已經提供了A類和B類的實現,你應該能夠使用polymorphism,並且從指針/引用調用open()/ close()而不是A或B.

而不是爲A和B創建兩個數組,則只能創建一個Base指針數組。

例子:

Base* base[basenum]; 

void openAnyClass(const int i) 
{ 
    if(i < basenum && i >=0 && base[i] != NULL) 
     base[i]->open(); 
} 

int main(void) 
{ 
    base[0] = new A(); 
    base[1] = new B(); 
    ... 
    openAnyClass(1); 
    closeAnyClass(2); 

    for(int i = 0 ; i < basenum ; i++) 
     delete base[i]; 
} 

作爲一個方面說明,我認爲這將是更好地使像這些用的開啓和關閉功能:

void openAnyClass(Base& base); 
void closeAnyClass(Base& base); 

而不是使用一個全局變量來存儲對象並傳遞索引,將對象的指針/引用傳遞給函數,函數將調用適當的方法(不管A或B的方法)。

+0

如果你打算採用這種方法,最好創建一個'vector base;'而不是C風格的數組,並修改'delete'-loop來迭代while'i <= base.size()'。現在你可能會刪除未分配的指針... – 2012-07-09 11:45:11

相關問題