Sto ricominciando a usare C++ dopo quasi un decennio di arrugginimento

Cerco di sintetizzare la domanda e poi vi mostro il codice:
- ho una classe B con un constructor che richiede un parametro.
- ho una classe A che ha come membro privato un'istanza di B
- come istanziare B all'interno del constructor di A se al momento non conosco ancora il parametro di inizializzazione per B?
Qui un esempio concreto (gli include guards ci sono, li ho omessi per leggibilità).
La classe B si chiama bar e implementa un counter che deve essere inizializzato. Sono disponibili i metodi per leggerne il valore e per incrementarlo di un unità:
bar.h
- Codice: Seleziona tutto
class bar {
public:
bar (unsigned int init);
~bar();
unsigned int getCount();
void incrementCount();
private:
unsigned int _count;
};
bar.cpp
- Codice: Seleziona tutto
#include "bar.h"
bar::bar(unsigned int init)
{
_count = init;
}
bar::~bar() = default;
unsigned int bar::getCount()
{
return _count;
}
void bar::incrementCount()
{
_count++;
}
La classe A ci chiama in realtà foo ed è in sostanza un wrapper per il counter implementato in bar che incrementa il valore solo se non si è superato un certo valore massimo settato all'inizializzazione.
foo.h
- Codice: Seleziona tutto
#include "bar.h"
class foo
{
public:
foo (unsigned int max);
~foo();
unsigned int getCountCapped();
void incrementCountCapped();
private:
const unsigned int _max;
bar _counter;
};
foo.cpp
- Codice: Seleziona tutto
#include "foo.h"
foo::foo (unsigned int max) : _max(max) {}
foo::~foo () = default;
unsigned int foo::getCountCapped()
{
return _counter.getCount();
}
void foo::incrementCountCapped()
{
if (_counter.getCount() < _max)
_counter.incrementCount();
}
Questo codice non compila e credo di sapere il perché: quando chiamo il constructor per foo, il membro di tipo bar viene inizializzato anche lui, ma per farlo al compiler serve un default constructor (che non ho e che non posso avere perché non esiste un valore che per l'inizializzazione che possa essere considerato di default). Se aggiungo al codice di cui sopra un constructor che non prende argomenti e inizializza a zero, tutto funziona bene, ma non è quello che voglio.
Ho provato a risolvere transformando il membro in una referenza all'oggetto:
- Codice: Seleziona tutto
private:
bar &_counter;
In modo che il compiler debba solo riservare lo spazio per il pointer in memoria, ma nemmeno così funziona.
Come si agisce in un caso del genere?
Grazie, Boiler
