2012-07-09 48 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

相关问题