2010-10-15 21 views
5

tengo un programa y muchos de sus clases tienen algunos operadores y métodos con la palabra clave const como los siguientes:const y no const methods in C++?

operator const char*() const; 
operator char*(); 
void Save(const char *name) const; 
void Load(const char *name); 

En primer lugar: ¿qué significa const al final de la declaración del método ?, ¿es el lo mismo que ponerlo al principio?

Segundo: ¿Por qué sería necesaria una versión const y una versión no const de operator()?

Gracias de antemano.

Respuesta

2

'const' al final le dice al compilador que este método no cambia ninguna variable miembro - que es seguro llamar a este método en las instancias const. Entonces, se podría llamar a Save en una instancia de const, ya que no cambiará esa instancia. Cargar, por otro lado, cambiará la instancia, por lo que no se puede usar en instancias const.

La versión const del operador() devuelve un puntero constante, lo que garantiza que el búfer pasado no cambiará. Es de suponer que es un puntero a una variable de instancia de la clase. Para instancias no const, el otro operador() devuelve un puntero no const. Tendría que ser un puntero a alguna memoria que, incluso si se escribía en, no cambiaría el contenido de la instancia.

Además, busque alguna vez la palabra clave 'mutable'. Comprender eso te ayudará a entender esta idea de const-correctness.

2

Constness de la función del miembro. Significa que la función no puede (*) modificar ninguna de sus variables miembro. Es como poner un const frente a todas las variables de miembro para esta llamada a una función. Es una buena garantía para los clientes de su clase y también puede ayudar en la optimización del compilador.

(*) - vea también la palabra clave mutable.

8

Primero: ¿qué significa const al final de la declaración del método ?, ¿es lo mismo que ponerlo al principio?

No. A const al final significa que el método puede ser llamado en los objetos que se declaran const. Un const al principio significa que el valor devuelto es const.

Segundo: ¿Por qué sería necesaria una versión const y una versión no const de operator()?

La versión no const devuelve char* que no es const. Al modificar este char*, podría modificar el objeto (suponiendo que el char* es miembro del objeto).

Puesto que esto no está permitido para const objetos, hay una sobrecarga de operator() para objetos const, de modo que un const char* se devuelve, por lo que el objeto no se puede modificar a través de él.

+1

Ok, recupero mi respuesta, la tuya es mucho más clara. –

1

Al poner const al final de una declaración de método se indica que el objeto en sí, o this, es const en lugar del tipo de devolución.

C++ permite que los métodos se sobrecarguen en const por razones complicadas. No hay suficiente espacio para entrar en detalles completos aquí. Pero aquí hay un par de breves.

  • Ocassionally hay un valor, o necesidad plana, en tener un método comportan de manera diferente cuando se le llama desde un tipo const. El ejemplo más sencillo es cuando desea devolver un valor const desde un método const y un valor no const desde un método normal.
  • Si this es o no const cambia drásticamente la vinculación del método interno. Hasta el punto de que esencialmente se convertiría en dos cuerpos de método diferentes. Por lo tanto, tiene sentido dividirlo en 2 métodos diferentes.
0
  1. Const al principio se aplica al valor de retorno. Const al final se aplica al método en sí. Cuando declaras un método como "const" estás diciendo que no tienes intención de modificar ninguna de las variables miembro de la clase en el método. El compilador incluso hará algunas comprobaciones básicas para asegurarse de que el método no modifique las variables miembro. La const en el valor de retorno impide que la persona que llama modifique el valor que se devuelve. Esto puede ser útil cuando devuelve punteros o referencias a datos administrados por la clase. Esto se hace a menudo para evitar devolver copias de datos complejos que podrían ser costosos en tiempo de ejecución.

  2. La razón por la que tiene dos operadores diferentes es que la versión "const" devuelve un puntero const a lo que probablemente sea datos internos de la clase. Si la instancia de la clase es const, entonces es probable que desee que los datos devueltos también sean const. La versión "no const" simplemente proporciona un método que devuelve un valor de retorno modificable cuando el llamante tiene una instancia no const de la clase.

1

Una nota además de las otras respuestas: no hay operator() en su ejemplo.

operator const char*() const; 
operator char*(); 

son operadores de conversión, lo que significa que los objetos de la clase se pueden convertir implícitamente a cadenas estilo C, como

void f(const MyClass& x, MyClass& y) { 
    const char* x_str = x; 
    char* y_str = y; 
} 

una declaración y uso de operator(), lo que significa que puede utilizar un objeto del tipo de clase como una especie de función, se vería así:

class MyClass { 
public: 
    const char* operator() (int x, int y) const; 
    // ... 
}; 

void g(const MyClass& obj) { 
    const char* result = obj(3, 4); 
} 
1

Si usted está buscando un gran recurso en C++ (incluyendo consejos sobre el uso const correctamente) intente con "C++ efectivo".

Un sitio útil sobre: ​​JRiddel.org

En C++ cuando se declara un método const poniéndolo después de la firma del método que está afirmando que "Este método no va a cambiar las variables de instancia no mutable en el objeto que está siendo llamado ".

El const antes de que el valor de retorno (por ejemplo, la const en: operator const char*...") está declarando que sólo devuelve un puntero variable a un const char*. (No puede cambiar el contenido del char*, pero puede volver a asignar el puntero.) Si escribió "const char* const ...", sería un puntero constante a los caracteres constantes. (El const viene después de la estrella).

Las versiones múltiples son útiles por lo que el compilador puede entender esto:

const char* my_const_var = <object_name>(); 
char* my_var = <object_name>(); 

Chris

1

Debe referirse a la "ALTA · INTEGRIDAD C++ codificación manual STANDARD" para saber cuándo se recomienda utilizar el const modificador de miembros de la clase: Regla

alta integridad CPP 3.1.8: Declare 'const' cualquier función de miembro de clase que no modifique el estado externo visible del objeto. (QACPP 4211, 4214)

Justificación: aunque el lenguaje impone la corrección de const bitwise, const correctness debe considerarse lógico, no bitwise. Una función miembro debe declararse const si es imposible para un cliente determinar si el objeto ha cambiado como resultado de llamar a esa función. La palabra clave "mutable" se puede usar para declarar datos de miembros que se pueden modificar en funciones const, esto solo se debe usar cuando los datos de miembros no afecten el estado externamente visible del objeto.

class C 
{ 
public: 
    const C& foo() { return * this; } // should be declared const 
    const int& getData() { return m_i; } // should be declared const 
    int bar() const { return m_mi; }  // ok to declare const 
private: 
int m_i; 
mutable int m_mi; 
}; 

Referencia Effective C++ Item 21; Industrial Strength C++ 7.13;