Pregunta ¿Cuál es el punto de un miembro de datos const no estático? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Para el siguiente código:

class A
{
public:
    const int cx = 5;
};

Aquí, se creará una instancia de cx para cada objeto de A. Lo que me parece un desperdicio, ya que cx nunca puede modificarse. En realidad, no veo ninguna razón por la cual el compilador no haga cumplir haciendo estático un miembro de datos const. ¿Alguien por favor me puede explicar esto?


5
2017-11-03 17:59


origen


Respuestas:


Un miembro de datos const no tiene que ser el mismo para todas las instancias. Puedes inicializarlo en el constructor.

class A
{
public:
    A(int n) :cx(n) {}

    const int cx;
};

int main()
{
    A a1(10);
    A a2(100);
}

9
2017-11-03 18:02



En realidad, no veo ninguna razón por la cual el compilador no deba hacer cumplir   un miembro de datos const estático.

¿Has considerado eso cx podría inicializarse en el constructor con un valor conocido en tiempo de ejecución, y variar entre diferentes instancias de A?
const los miembros hacen que la asignación a ellos sea imposible, pero a veces tener un miembro que no puede cambiar su valor inicial resulta útil.

Definitivamente no es el mejor ejemplo, sino para ilustrar la idea:

struct Multiplier
{
    const int factor;

    Multiplier(int factor) : factor(factor) {}

    int operator()( int val ) const
    {
        return val * factor;
    }
};

std::vector<int> vec{1, 2, 3};
std::vector<int> vec2;

int i;
std::cin >> i;

std::transform( std::begin(vec), std::end(vec),
                std::back_inserter(vec2), Multiplier(i) );

// vec2 contains multiples of the values of vec

6
2017-11-03 18:03



Si el valor se inicializa con una constante, como en su ejemplo, probablemente sea mejor que sea estático. Pero eso no siempre es el caso; Es bastante frecuente tener algo como:

class Matrix
{
    const int myRowCount;
    const int myColumnCount;
    std::vector<double> myData;
    //  ...
public:
    Matrix( int rows, int columns )
        : myRowCount( rows )
        , myColumnCount( columns )
        , myData( rows * columns )
    {
    }
    //  ...
};

En este caso, el const expresa claramente que el número de Las filas y columnas en cualquier instancia dada no cambiarán. (Sobre el Por otro lado, bloquea el operador de asignación predeterminado de ser generado. Que puede o no ser una buena cosa.)


1
2017-11-03 18:06



Hay algunas limitaciones en el uso de miembros const no estáticos.

Digamos que hay un empleado de la clase. Primero, aunque el compilador puede generar un constructor de copia que funcione correctamente, no puede generar un operador de asignación. Si un programa crea dos objetos Employee e1 y e2, la instrucción e1 = e2 causará un diagnóstico del compilador. Esta asignación no es válida porque implícitamente intenta cambiar el valor del miembro const. Aunque puede tener un operador de asignación al descartar const-ness, pero esa no es una buena idea.

Otra limitación es que es difícil proporcionar un constructor predeterminado útil para esta clase. Un constructor predeterminado es esencial si desea crear, por ejemplo, matrices de objetos Employee. Definir un constructor por defecto es un poco complicado; lo principal que se debe recordar es que los miembros const de datos no estáticos se inicializan en la lista de inicialización del constructor, y usted debe inicializarlos todos. El constructor predeterminado debe establecer el campo dob en algún valor, y este valor no se puede modificar posteriormente. Así que la matriz construida será prácticamente inútil.


0
2017-11-03 18:08