2012-04-04 6 views
5

que tienen alguna clase Foo y Registrador:¿Cómo crear una matriz con un miembro de referencia en C++?

class Logger{/* something goes here */}; 
class Foo{ 
    Foo(Logger& logger); 
    Logger& logger; 
} 

Foo::Foo(Logger& logger) : logger(logger) 
{} 

Ahora quiero crear una matriz de objetos de la clase Foo, donde todas las referencias Foo::logger debe apuntar a la misma Logger objeto. He intentado algo así como (necesito tanto pila y asignación del montón):

Logger log (/* parameters */); 
Foo objects [3] (log); // On stack 
Foo* pObjects = new Foo [3] (log); // On heap 

El problema es que ambas versiones tratan de llamar al constructor por defecto Foo() que no está presente. Además, como entiendo, no es posible cambiar la variable referenciada de una referencia. Por lo tanto, una llamada temporal al constructor predeterminado y una posterior integración en un bucle tampoco ayudan.

Entonces: ¿Cuál es la forma correcta de hacerlo? ¿Debo usar punteros al objeto Logger?

Respuesta

2

Para usos generales normalmente hago un registrador de Singleton, por lo que solo hay uno y se puede acceder desde todos los componentes. http://en.wikipedia.org/wiki/Singleton_pattern

Esto también hace que el constructor de Foo sea mucho más simple.

class Logger 
{ 
    public: 
     static Logger& getInstance() 
     { 
      static Logger instance; 
      return instance; 
     } 

     public log(const std::string& txt) 
     { 
      //do something 
     } 

    private: 
     Logger() {} 
     Logger(Logger const&);    // Don't Implement. 
     void operator=(Logger const&); // Don't implement 
}; 

y utilizarlo en Foo como:

Logger::getInstance().log("test"); 

o

Logger& logger = Logger::getInstance(); 
logger.log("test"); 

(Créditos para singleton de @Loki Astari: C++ Singleton design pattern)

+0

Para estar seguro de que lo entiendo: ¿Quiere decir algún miembro estático para todos los objetos? ¿Cómo inicializarlo entonces? ¿O un objeto separado/variable global/...? –

+0

Se refiere a una clase singleton a la que se puede acceder desde cualquier lugar de su código. Esta es la forma común para los madereros. – giorashc

5

No puede inicializar una matriz de objetos con un constructor no predeterminado. Sin embargo, puede utilizar un vector como se muestra here (Mira la primera respuesta)

Y para el montón se puede hacer lo siguiente:

Foo* pObjects[3]; 

for (int i = 0; i < 3; ++i) { 
    pObjects[i] = new Foo(log); 
} 
2

Puede inicializar una matriz de objecs con la no predeterminado constructor utilizando la llave de C++ 11 inicialización:

class Logger{/* something goes here */}; 
class Foo{ 
public: 
    Foo(Logger& logger); 
private: 
    Logger& logger; 
}; 

Foo::Foo(Logger& logger) : logger(logger) 
{} 


EDITAR: En C++ 11, puede utilizar vector para hacer lo que desee:

#include <vector> 
class Logger{/* something goes here */}; 
class Foo{ 
public: 
    Foo(Logger& logger) : logger(logger) {} 
private: 
    Logger& logger; 
}; 

int main() { 
    Logger log; 
    std::vector<Foo>(3, log); 
} 

Tenga en cuenta que la solución vector no funcionará en C++ 03. En C++ 03 ese constructor vectorial invoca Foo::operator=. En C++ 11 invoca Foo::Foo(const Foo&).

+0

que sólo funciona si conozco el cantidad de elementos a priori, ¿verdad? Esto no siempre es cierto para mi problema. –

+0

Es cierto, eso es un problema. Pero tenga en cuenta que debe saber la cantidad de elementos * a priori * cuando crea matrices en la pila. –

Cuestiones relacionadas