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 consttanto en el constructor de copia y la doNotChangeMyDatafunción de hacerlo de modo que ptrno 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 ptrla matriz se constmodifique 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::vectorstd::vector::operator[]()puede modificar los valores ¿verdad?vectorfuncionaría.std::vector::operator[]() constdevuelve unaconstreferenciaRespuestas:
Los punteros no se propagan
const. Agregarconstal tipodouble*rendimientosdouble* const, lo que resulta en un valor noconstl 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_ptrpara evitar la gestión manual de la memoria. Puede usar elstd::experimental::propagate_constcontenedor 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::arrayno funciona, si no conoce el tamaño en el momento de la compilación.vectoragrega gastos generales;unique_ptrno agrega sobrecarga, pero si el puntero necesita ser compartido, entonces necesitashared_ptrlo 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) :(vectorTBH 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.vectorluego 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.