c++ - funcion - Significado de ''const'' último en una declaración de función de una clase?
funcion pi en c++ (7)
¿Cuál es el significado de const
en declaraciones como estas? La const
me confunde.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Cuando agrega la palabra clave const
a un método, this
puntero se convertirá esencialmente en un puntero al objeto const
y, por lo tanto, no podrá cambiar ningún dato de miembro. (A menos que use mutable
, más sobre esto más adelante).
La palabra clave const
es parte de la firma de funciones, lo que significa que puede implementar dos métodos similares, uno que se llama cuando el objeto es const
y otro que no lo es.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
Esto dará salida
Foo
Foo const
En el método non-const puede cambiar los miembros de la instancia, lo que no puede hacer en la versión const
. Si cambia la declaración del método en el ejemplo anterior al código a continuación, obtendrá algunos errores.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
Esto no es completamente cierto, ya que puede marcar un miembro como mutable
y un método const
puede cambiarlo. Se utiliza principalmente para contadores internos y esas cosas. La solución para eso sería el siguiente código.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++;
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "The MyClass instance has been invoked " << ccc.GetInvocations() << " times" << endl;
}
que daría salida
Foo
Foo const
The MyClass instance has been invoked 2 times
El calificador const
significa que los métodos se pueden llamar en cualquier valor de foobar
. La diferencia viene cuando consideras llamar a un método no constante en un objeto const. Considere si su tipo de foobar
tenía la siguiente declaración de método adicional:
class foobar {
...
const char* bar();
}
La bar()
método bar()
no es constante y solo se puede acceder desde valores no constantes.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won''t compile
const char* v2 = fb2.bar(); // works
}
La idea detrás de const
es marcar métodos que no alteren el estado interno de la clase. Este es un concepto poderoso, pero en realidad no es ejecutable en C ++. Es más una promesa que una garantía. Y uno que a menudo se rompe y se rompe fácilmente.
foobar& fbNonConst = const_cast<foobar&>(fb1);
Estas constantes significan que el compilador producirá un error si el método ''con const'' cambia los datos internos.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
La prueba
int main()
{
const A a1;
a1.badGetter(); // doesn''t work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Lea this para más información.
La const significa que el método promete no alterar a ningún miembro de la clase. Podrías ejecutar los miembros del objeto que están tan marcados, incluso si el objeto en sí estuviera marcado como const
:
const foobar fb;
fb.foo();
seria legal
Consulte ¿Cuántos y cuáles son los usos de "const" en C ++? para más información.
La respuesta de Blair está en la marca.
Sin embargo, tenga en cuenta que hay un calificador mutable
que se puede agregar a los miembros de datos de una clase. Cualquier miembro así marcado puede modificarse en un método const
sin violar el contrato const
.
Es posible que desee utilizar esto (por ejemplo) si desea que un objeto recuerde cuántas veces se llama a un método en particular, sin afectar la constancia "lógica" de ese método.
cuando usa const
en la firma del método (como su dicho: const char* foo() const;
) le está diciendo al compilador que la memoria apuntada por this
no se puede cambiar con este método (que es foo
aquí).
Significado de una función miembro Const en C ++ Conocimiento común: la programación intermedia esencial brinda una explicación clara:
El tipo de este puntero en una función miembro no constante de una clase X es X * const. Es decir, es un puntero constante a una X no constante (consulte los punteros Const y los punteros a Const [7, 21]). Debido a que el objeto al que se refiere esto no es constante, se puede modificar. El tipo de esto en una función miembro constante de una clase X es const X * const. Es decir, es un puntero constante a una X constante. Debido a que el objeto al que hace referencia es const, no se puede modificar. Esa es la diferencia entre las funciones miembro const y non-const.
Así que en tu código:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Puedes pensarlo así:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};