Cześć, wczoraj spotkałem się z takim problemem i do dziś rozwiązałem to w taki sposób. No nie wiem czy da się to lepiej rozwiązać, przy założeniach, które muszę spełnić. Może ktoś będzie miał jakiś fajny sprytny pomysł. O co chodzi.
To jest uproszczony schemat klas.
Mam strukturę Foo i klasę Bar, która jest immutable i przechowuje z góry określoną ilość swoich obiektów w tablicy statycznej S_BARS. Dodatkowych obiektów klasy Bar poza tymi w tejże tablicy S_BARS nie wolno tworzyć (taki ustalony zbiór singletonów).
A każdy zaś obiekt tej klasy przechowuje tablicę wskaźników na strukturę Foo (która może być również pusta).
W rzeczywistym problemie obiektów klasy Foo również nie można tworzyć samemu i też tworzą ustalony zbiór singletonów ale nie będę zaciemniał problemu, wiec uznajmy, że Foo wygląda jak wygląda.
Plik main.cpp
struct Foo {
Foo(int val) : value(val) {}
int getValue() const { return value; }
private:
const int value;
} foo1(1), foo2(2), foo3(3);
class Bar {
public:
static const Bar& instance(int i) { return S_BARS[i]; }
Bar(const Bar& obj) = delete; /* Zeby byla tylko jedna inst. na kazdy obiekt Bar */
int count() const { return m_count; }
const Foo& foo(int i) const { return *m_foos[i]; }
private:
Bar(int count, const Foo** pFoos) : m_count(count), m_foos(pFoos) {} /* K-tor prywatny */
private:
static const Bar S_BARS[];
const int m_count; // ilosc elementow w m_foos ponizej;
const Foo** m_foos;
};
const Foo* pFooNull[] = {};
const Foo* pFoo1 [] = {&foo1};
const Foo* pFoo3 [] = {&foo1, &foo2, &foo3};
const Bar Bar::S_BAR[] = { {0, pFooNull}, {1, pFoo1}, {3, pFoo3} };
I chodzi o to, że o ile ten kod działa poprawnie, to nie specjalnie podoba mi się to, że aby zainicjalizować zmienną S_BARS (w linii 30), to muszę użyć dodatkowych zmiennych
const Foo* pFooNull[] = {};
const Foo* pFoo1 [] = {&foo1};
const Foo* pFoo3 [] = {&foo1, &foo2, &foo3};
Inaczej mówiąc chciałbym żeby linia 30 wyglądała np. tak:
const Bar Bar::S_BARS[] = { {0, {}}, {1, {&foo1}}, {3, {&foo1, &foo2, &foo3}} };
Bo tych zmiennych w ogóle nie potrzebuję.
ROZWIĄZANIE NR 2
Można też użyć zamiast tablicy wskaźników const Foo** m_foos; wektora std::vector<const Foo*> m_foos; i nieznacznie zamieniając k-tor na
Bar(int count, const std::vector<const Foo*>& vFoos) : m_count(count), m_foos{vFoos} {} da się już zainicjalizować tę stałą S_BARS w sposób jaki oczekuję.
Tylko pytanie jest takie, czy można właśnie to zrobić używając tablicy w stylu C (i to jeszcze bez konstruktów typu new)?