-2
#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 类中会有不同的实现。A 类中的 open() 可以从多个客户端调用,并且最多可以调用。不。客户的数量是 # 定义的。

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

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

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

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

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

4

3 回答 3

1

这就是拥有您从中派生的命令基类的原因;这样你就可以拥有一个类的指针或引用,并通过虚函数调用派生类中的打开/关闭方法。

所以如果你有

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()否则您会遇到内存泄漏。

于 2012-07-09T10:26:56.017 回答
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 方法

于 2012-07-09T10:27:13.137 回答
0

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

您可以只创建一个 Base 指针数组,而不是为 A 和 B 创建两个数组。

例子:

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

于 2012-07-09T10:32:30.053 回答