Pregunta El significado de 'const' es el último en una declaración de función de una clase?


Cuál es el significado de const en declaraciones como estas? los const me confunde.

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

590
2018-04-15 13:27


origen


Respuestas:


Cuando agrega el const palabra clave a un método del this puntero se convertirá esencialmente en un puntero a const objeto, y por lo tanto no puede cambiar ningún dato de miembro. (A menos que use mutable, más sobre eso más tarde).

los const palabra clave 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 consty uno 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 producirá

Foo
Foo const

En el método non-const puede cambiar los miembros de la instancia, lo que no puede hacer en el const versión. Si cambia la declaración de método en el ejemplo anterior al código siguiente, 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, porque puede marcar a un miembro como mutable y un const método puede entonces cambiarlo. Se usa principalmente para contadores internos y demás. 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;
}

cuál saldría

Foo
Foo const
The MyClass instance has been invoked 2 times

774
2018-04-15 13:49



La const significa que el método promete no alterar ningún miembro de la clase. Podrías ejecutar los miembros del objeto que están marcados así, incluso si el objeto en sí estaba marcado const:

const foobar fb;
fb.foo();

sería legal

Ver ¿Cuántos y cuáles son los usos de "const" en C ++? para más información.


170
2018-04-15 13:29



los const calificador significa que los métodos se pueden invocar en cualquier valor de foobar. La diferencia se presenta cuando consideras llamar a un método no const en un objeto const. Considera si tu foobar tipo tenía la siguiente declaración de método adicional:

class foobar {
  ...
  const char* bar();
}

El método bar() es no const y solo se puede acceder desde valores no const.

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 const aunque es para marcar métodos que no alterarán el estado interno de la clase. Este es un concepto poderoso pero en realidad no se puede hacer cumplir 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);

38
2018-04-15 13:30



Estas const significan que el compilador tendrá 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
}

Leer esta para más información


20
2018-04-15 13:30



La respuesta de Blair está en la marca.

Sin embargo, tenga en cuenta que hay un mutable calificador que puede agregarse a los miembros de datos de una clase. Cualquier miembro así marcado poder ser modificado en una const método sin violar el const contrato.

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 constidad "lógica" de ese método.


9
2018-04-15 13:37



Significado de una función miembro de Const en Conocimiento común de C ++: Programación intermedia esencial da una explicación clara:

El tipo de este puntero en una función miembro no consistente de una clase   X es X * const. Es decir, es un puntero constante a una X no constante   (ver los indicadores y punteros de Const para Const [7, 21]). Porque el objeto   a lo que esto se refiere no es const, se puede modificar. El tipo de   esto en una función de miembro constante de una clase X es const X * const. Ese   es, es un puntero constante a una constante X. Porque el objetivo de   lo que esto se refiere es const, no puede ser modificado. Eso es   diferencia entre las funciones miembro const y non-const.

Entonces 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;
};

6
2018-03-14 05:48



cuando usas const en la firma del método (como dijiste: const char* foo() const;) le está diciendo al compilador que la memoria apuntada por this no puede ser cambiado por este método (que es foo aquí).


4
2018-05-30 05:54