C ++调用驻留在多个类中的函数

时间:2012-07-09 10:02:46

标签: c++

#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);   
}

我希望实现这样的功能。

openAnyClass(1);
CloseAnyClass(2); 

这两个函数应该能够从A类和B类中的任何一个调用open()和close()。

openAnyClass(1)将调用classA或classB数组中第一个对象的open()函数。

open() - >将在A类和B类中具有不同的实现,并且可以从多个客户端调用classA中的open()。没有。客户是#defined。

每次只调用一个来自classA或classB的open()。我不想拥有相同代码的几个副本。

只有一个函数我想要调用任何A类和任何客户端的open()。

对于Eg:在下面的语句中我想调用client1的A类的open()。 openAnyClass(int)的参数表示客户端ID。这也可能意味着classB[1].open();

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

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分: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()获取的所有内容,否则您将会出现内存泄漏。

答案 1 :(得分:0)

所以classA是A的数组,对于classB也是如此。并且调用openAnyClass(1),意味着在A的所有实例上调用open(),而closeAnyClass()意味着在classB的所有实例上调用close()。如果是这种情况,那么这个问题实际上很复杂。

无论如何,没有任何已知的开箱即用方法可以做到这一点。你必须迭代数组的所有元素并调用open()或close()。或者你可以使用boost foreach http://www.boost.org/doc/libs/1_39_0/doc/html/foreach.html 或实施自己的foreach方法

答案 2 :(得分:0)

如果我正确理解你的问题,你想调用纯虚函数的不同实现。假设您已经提供了A类和B类的实现,您应该能够使用polymorphism并从指向Base的引用而不是A或B调用open()/ close()。

不是为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的方法)。