Ubicación constante para detener la edición de datos del puntero con boostshared_ptr
Pregunta
Entonces Wikipedia me dice (creo correctamente) que para detener la edición de los datos de un puntero y el puntero en sí, debo hacer esto:
void function(int const * const var)
¿Es esto lo mismo que esta función?
void function(const int * const var)
¿Y en ese caso por qué está permitido?Porque sé que no puedes hacer esto debido a un error de compilación constante duplicado:
void function(const int const * const var)
Básicamente quiero hacer lo mismo con un puntero de impulso.¿Haría esto?
void function(const boost::shared_ptr<int> const var)
¿Y cómo afectaría esto mi capacidad para recorrer, digamos, un puntero compartido a un vector?¿Podría hacer esto con ese guardia?
void function(const boost::shared_ptr<std::vector<int>> const var)
{
for (unsigned int i = 0; i < var->size(); ++i)
{
std::cout << var[i];
}
}
Adición:Después de la respuesta de Brian
Entonces, si creo un puntero como este:
boost::shared_ptr<vector<int>> lala
Y lo uso en esta función:
function (const boost::shared_ptr<std::vector<const int>> var)
¿Eso funcionará?
Solución
Sí, int const * const var
es lo mismo que const int * const var
.Puedes poner const
antes o después del tipo que modifica, por "razones históricas".Ver http://www.stroustrup.com/bs_faq2.html#constplacement
Para un objeto de puntero inteligente, de hecho no puedes hacer
const boost::shared_ptr<int> const
porque ambos const
s modificar el mismo tipo.En cambio, quieres
const boost::shared_ptr<const int>
La primera const
evita que el puntero sea modificado (es decir., reasignado para señalar a otro int
) y el const
en el parámetro de plantilla le dice al objeto operator*
para devolver un const int&
, lo que impide la modificación de la int
señaló.
Esto no impide la iteración sobre un vector u otro contenedor de la manera que ha descrito, por la misma razón por la que aún puede iterar sobre un const
vector normalmente.
Editar en respuesta a la pregunta editar:
Esto funciona:
void f(const boost::shared_ptr<const std::vector<int> > var);
// ...
boost::shared_ptr<vector<int> > lala;
f(lala);
La primera const
en el parámetro no afecta en absoluto el paso de parámetros;solo le dice a la función en sí que no modifique el parámetro.La razón por la que podemos agregar un const
en el parámetro de plantilla es que un boost::shared_ptr<T>
se puede inicializar desde boost:shared_ptr<U>
dónde T
y U
no son necesariamente del mismo tipo, siempre y cuando U*
es implícitamente convertible a T*
.Si T
es lo mismo que U
excepto con mayor calificación cv, como en este caso, la conversión es posible.
no lo hagas std::vector<const int>
.Estoy bastante seguro de que eso no es legal.(Al menos he recibido varias pantallas de errores de compilación cada vez que lo he probado).
Otros consejos
const antes o después del INT es lo mismo, así que:
int const * var
y
const int * var
son iguales y significan que el valor apuntado no se puede cambiar
const después de * significa que el puntero no puede ser reasignado.
Si entiendo correctamente, le gustaría hacer el vector const.Si ese es el caso, la sintaxis sería esta:
void function(const boost::shared_ptr<const std::vector<int>>& var)
El puntero inteligente se pasa por const referencia porque es más barato que pasar el puntero inteligente por valor y tiene el mismo efecto.El objeto apuntado por el puntero inteligente es inmutable al declarar que el tipo IT señala como const.
Usted ha razonado correctamente que const shared_ptr<Foo>
no hace que Foo sea un objeto Const.Esta "laguna" se describe en wikipedia .En su lugar, debe cambiar el tipo de puntero almacenado por BOOST :: shared_ptr.Esto se puede hacer en el argumento de la plantilla en sí:
void function(const boost::shared_ptr<const std::vector<int>>& var)
BOOST :: Shared_PTR tiene un constructor de copia que permite que se copie un tipo Const que se copie de un tipo que no se puede copiar.Lo contrario no debe ser posible.
¿Antes o después?
Las dos líneas siguientes son semánticamente equivalentes, ambas declaran un puntero cuyo valor no se puede cambiar, que se refiere a un int
eso no se puede cambiar.
int const * const p1 = ...;
const int * const p2 = ...;
El constante La palabra clave se une a lo que esté directamente a la izquierda, a menos que no hay nada a la izquierda, en cuyo caso abrazará lo que esté a la derecha.
Cuanto más const
, ¿el mejor?
typedef boost::shared_ptr<int> shared_int_ptr;
const shared_int_ptr const p3; // ill-formed
Lo anterior definición de tipo se proporciona para que sea más fácil ver que boost::shared_ptr<int>
es un solo nombre, y por lo tanto no podemos agregar const
a ambos lados;duplicar constantes (como mencionaste) no son C++ legales.
Simplemente aplicar uno tampoco sería suficiente, ya que eso haría que el envoltorio constante, pero no el objeto interno al que se refiere (el En t).
Anteriormente escribimos que boost::shared_ptr
debe envolver alrededor de un int
, pero como queremos hacer el tipo envuelto const
, Bueno..vamos a envolver el ptr_compartido alrededor de lo que queremos:
void func (const boost::shared_ptr<const int> foo);
en lo anterior func
no es capaz de modificar foo
, ni el int
referido por foo
.