Digamos que tengo una clase que se ve así (esto es solo un ejemplo):
class A {
double *ptr;
public:
A() : ptr( new double[100] ) {}
A( const A &other ) {
other.ptr[7] = 15;
}
void doNotChangeMyData() const {
ptr[43] = 14;
}
void changeMyData() {
ptr[43] = 14;
}
~A() { delete[] ptr; }
};
El const
tanto en el constructor de copia y la doNotChangeMyData
función de hacerlo de modo que ptr
no se puede cambiar; sin embargo, esto todavía me permite modificar el contenido de la matriz a la que apunta ptr
.
¿Hay alguna manera de evitar que el contenido de ptr
la matriz se const
modifique solo en instancias, salvo "tener cuidado" (o cambiar el puntero sin formato)?
Sé que podría hacer algo como
void doNotChangeMyData() const {
const double *const ptr = this->ptr;
ptr[43] = 14; // then this would fail to compile
}
Pero prefiero no tener que ...
std::vector
std::vector::operator[]()
puede modificar los valores ¿verdad?vector
funcionaría.std::vector::operator[]() const
devuelve unaconst
referenciaRespuestas:
Los punteros no se propagan
const
. Agregarconst
al tipodouble*
rendimientosdouble* const
, lo que resulta en un valor noconst
l cuando se desreferencia.En cambio, puede usar un
std::vector
:a
std::array
:o una matriz integrada (no recomendado):
Las tres opciones se propagan
const
.Si realmente desea utilizar punteros (no se recomienda encarecidamente), al menos utilice a
std::unique_ptr
para evitar la gestión manual de la memoria. Puede usar elstd::experimental::propagate_const
contenedor de la biblioteca fundamentos 2 TS:Todavía no está en el estándar, pero muchos compiladores lo admiten. Por supuesto, este enfoque es inferior a los contenedores adecuados.
fuente
std::array
no funciona, si no conoce el tamaño en el momento de la compilación.vector
agrega gastos generales;unique_ptr
no agrega sobrecarga, pero si el puntero necesita ser compartido, entonces necesitashared_ptr
lo que agrega sobrecarga. No creo que VS sea compatible actualmentepropagate_const
(al menos el archivo de encabezado al que hace referencia cppreference no existe/std:c++latest
) :(vector
TBH a menudo se sobreestima, especialmente en comparación con el esfuerzo de la gestión manual de la memoria. Además, si comparte los punteros manualmente, debe usar un recuento de referencia, por lo que la sobrecarga no es peculiarshared_ptr
. No sabía que VS aún no es compatiblepropagate_const
(GCC y Clang son compatibles con IIRC), pero no es difícil implementar el nuestro según las especificaciones.vector
luego tomo su contenido a través de.data()
o&vec[0]
y trabajo directamente con eso. En el caso de lo compartido, a menudo tengo un propietario del puntero que crea y elimina, pero otras clases comparten los datos.