2009-09-03 6 views
36

Estoy usando boost punteros compartidos en mi programa, y ​​tengo una clase que toma como parámetros una referencia a otro objeto. El problema que estoy en es la función make_shared requiere que todos los parámetros a ser una referencia constante, y me da errores de compilación si el constructor de mi clase no permite parámetros de referencia const a ser pasados ​​en.boost make_shared lleva en una referencia constante. ¿Alguna forma de evitar esto?

¿Alguien sabe la razón de ¿esta? Además, ¿hay algo que pueda hacer para evitar esto?

código de ejemplo de lo que me está dando problemas:

class Object 
{ 
    public: 
    Object(int& i) 
    { 
     i = 2; 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    int i = 0; 
    boost::shared_ptr<Object> obj = boost::make_shared<Object>(i); 
    return 1; 
} 

Esto da lugar a un error de compilación que indica la

siguiente: make_shared.hpp: 185: Error: ninguna función coincidente para la llamada a ` objeto :: objeto (const int &)' nota: los candidatos son: objeto :: objeto (objeto const &) nota: objeto :: objeto (int &)

Si el parámetro para el constructor de Objetos es un const int, esto funciona. Tengo curiosidad sobre por qué make_shared se comporta de esta manera.

+0

¿Puede mostrarnos algún código para demostrar cómo desea usar 'make_shared()'? – quamrana

+0

snippet de código publicado –

Respuesta

42

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/make_shared.html dice: "Si necesita pasar una referencia no constante a un constructor de T, puede hacerlo envolviendo el parámetro en una llamada a boost :: ref." Otro texto en esa página parece apoyar la respuesta de Rüdiger Hanke.

+0

impresionante, gracias. Realmente no quería usar mi solución a continuación. –

0

Aunque todavía no tengo idea de por qué impulsar make_shared me impone esta limitación, he encontrado una forma de evitarlo. Si paso en una referencia constante a un puntero del parámetro, puedo cambiar el puntero. Este es el fragmento de código:

class Object 
{ 
    public: 
    Object(int* const& i) 
    { 
     *i = 2; 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    int i = 0; 
    boost::shared_ptr<Object> obj = boost::make_shared<Object>(&i); 
    cout << i << "\n"; 
    return 1; 
} 

Esta funciona como un encanto. Sin embargo, ¿alguien tiene alguna idea de por qué necesito saltar estos aros? Parece extraño que make_shared me imponga esta limitación, aunque estoy de acuerdo en que probablemente sea una mala idea la mayor parte del tiempo.

8

No puedo hablar por los autores de la función, pero ... tienes que hacer una elección. Si la función usaría una referencia no constante, entonces no podría pasar los objetos const a los constructores que toman referencias const.

En mi experiencia, los constructores que toman referencias const son mucho más comunes que los constructores que toman referencias mutables.

constructores pueden tener n parámetros, por lo que no sólo puede proporcionar una única sobrecarga, pero tienen que tener en cuenta cualquier combinación de const/no constante que se traduce en una explosión exponencial de sobrecargas se necesitaría si' Quiero proporcionar sobrecargas para todos ellos. C++ 0x y el reenvío perfecto deberían proporcionar una solución para este problema, creo.

+0

Explicación perfecta. Gracias. –

1

Necesita definir un constructor de copia.

class Object 
{ 
    public: 
    Object(const Object& original) 
    { 
     // Copy original to new object 
     // The reason for the const is this should not change the original 
    }; 

    Object(int& i) 
    { 
     i = 2; 
    } 
}; 
4

Hasta rvalue references (ver la sección titulada "El problema de reenvío") llegan en C++ 0x, reenvío perfecto es casi imposible. make_shared hace lo mejor que puede con lo que se le da.

+0

+1 Alguien ha publicado una explicación de por qué es esto y no solo utiliza boost :: ref (..) :) – Nils

0

Es posible que pueda solucionarlo haciendo el constructor de Objetos explicit.

Cuestiones relacionadas