Управление объектом с несколькими указателями на него - PullRequest
0 голосов
/ 14 февраля 2019

Допустим, у меня есть два абстрактных класса, A1 и A2.A1 имеет функцию с именем foo(), A2 имеет функцию с именем bar().Я создаю много разных дочерних классов этих базовых классов, скажем C1,C2,C3, ..., которые могут наследовать или не наследовать A1 и / или A2. Теперь я хочу перебрать все классы типа A1 и всеклассы типа A2 и вызова foo() или bar().Мой вопрос: каков наилучший способ добиться этого?Мой подход состоит в том, чтобы использовать либо умные указатели, либо векторы, которые содержат экземпляры C1,C2,..., то есть:

std::vector<C1> c1s;
std::vector<C2> c2s;
std::unique_ptr<C3> c3;
...

Затем я объявляю два целых числа n_A1 и n_A2, которые указывают, сколько у меня есть экземпляров.каждого абстрактного класса A1 и A2.Затем я определяю два массива указателей:

A1 **a1s = new A1*[n_A1];
A2 **a2s = new A2*[n_A2];

и затем вручную добавляю все адреса экземпляров в эти массивы.Например, если c1s имеет длину 2, c2s имеет длину 3, и если C1 наследует A1, C2 наследует A2, C3 наследует A1 и A2, я бы сделал:

a1s[0]=&c1s[0];
a1s[1]=&c1s[1];
a2s[0]=&c2s[0];
a2s[1]=&c2s[1];
a2s[2]=&c2s[2];
a1s[2]=c3.get();
a2s[3]=c3.get();

Таким образом, n_A1=3 и n_A2=4, и теперь я могу перебирать массивы адресов a1s и a2s и вызывать функции foo() или bar().При удалении экземпляра, содержащего все эти объекты, мне просто нужно освободить массивы a1s и a2s.

. Постоянно рекомендуется не использовать необработанные указатели в C ++. Интересно, это хороший способрешить эту проблему?Есть ли риски с таким подходом?Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 14 февраля 2019
class IA
{
   virtual ~IA();
}

class A1 :public  IA
{
   virtual ~A1();
   virtual void foo();
}

class A2 :public  IA
{
   virtual ~A2();
   virtual void bar();
}

class C1 :public  A1
{
   virtual ~C1();
   virtual void foo();
}
class C2 :public  A2
{
   virtual ~C2();
   virtual void bar();
}
class C3 :public A1,public A2
{
   virtual ~C3();
   virtual void foo();
   virtual void bar();
}

int main()
{
  std::vector<IA*> AllAsObjects;
  AllAsObjects.push_back(new C1());
  AllAsObjects.push_back(new C2());
  AllAsObjects.push_back(new C3());
  for (IA* Obj :AllAsObjects)
  {
    if(dynamic_cast<A1*>(Obj))
      dynamic_cast<A1*>(Obj)->foo();
    if(dynamic_cast<A2*>(Obj))
      dynamic_cast<A2*>(Obj)->bar();
  }
}

Я думаю, это то, что вам нужно

* имейте в виду, что это скомпилировано

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...