Pergunta

Eu entendo que a função não tem permissão para alterar o estado do objeto, mas eu pensei que eu li em algum lugar que o compilador foi autorizado a supor que, se a função foi chamada com os mesmos argumentos, ele retornaria o mesmo valor e portanto, poderia reutilizar um valor em cache se ele estava disponível. por exemplo.

class object
{
    int get_value(int n) const
    {
        ...
    }

...


object x;

int a = x.get_value(1);
    ...
int b = x.get_value(1);

então o compilador poderia otimizar a segunda chamada de distância e usar o valor num registo ou simplesmente não fazer b = a;

Isso é verdade?

Foi útil?

Solução

const é sobre a semântica do programa e não sobre detalhes de implementação. Você deve marcar uma função membro const quando isso não muda o estado visível do objeto, e deve ser exigível em um objeto que é a própria const. Dentro de uma função de membro const numa X classe, o tipo de this é X const *: ponteiro para objeto X constante. Assim, todas as variáveis ??de membros são efectivamente const dentro dessa função de membro (excepto aqueles mutable). Se você tem um objeto const, você só pode chamar funções membro const nele.

Você pode usar mutable para indicar que uma variável de membro pode mudar mesmo dentro de uma função membro const. Isso normalmente é usado para identificar as variáveis ??usadas para armazenar em cache resultados, ou para as variáveis ??que não afetam o estado observável real tais como mutexes (você ainda precisa para travar o mutex nas funções membro const) ou contadores de uso.

class X
{
    int data;
    mutable boost::mutex m;
public:
    void set_data(int i)
    {
        boost::lock_guard<boost::mutex> lk(m);
        data=i;
    }
    int get_data() const // we want to be able to get the data on a const object
    {
        boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
        return data;
    }
};

Se você armazenar os dados pelo ponteiro em vez de diretamente (incluindo ponteiros inteligentes, como std::auto_ptr ou boost::shared_ptr), em seguida, o ponteiro se transforma const em uma função membro const, mas não os dados apontou-a, para que possa modificar o apontado para dados.

Como para armazenamento em cache: em geral, o compilador não pode fazer isso porque o Estado pode mudar entre as chamadas (especialmente no meu exemplo de multi-threaded com a exclusão mútua). No entanto, se a definição está em linha, em seguida, o compilador pode puxar o código na função de chamada e otimizar o que pode ver lá. Isso pode resultar na função efetivamente única a ser chamado uma vez.

A próxima versão do C ++ padrão (C ++ 0x) terá um novo constexpr palavra-chave. Funções marcado constexpr retornar um valor constante, de modo que os resultados podem ser armazenados em cache. Há limites sobre o que você pode fazer em função de tal (em ordem que o compilador pode verificar este fato).

Outras dicas

A palavra-chave mutável em variáveis ??de membro permite funções const para alterar o estado do objecto em questão.

E não, ele não cache de dados (pelo menos não todas as chamadas) desde o seguinte código é uma função const válido que muda ao longo do tempo:

int something() const { return m_pSomeObject->NextValue(); }

Note que o ponteiro pode ser const, embora o objeto apontado não é const, portanto, a chamada para NextValue em SomeObject pode ou não pode alterar o seu próprio estado interno. Isso faz com que a função de algo para retornar valores diferentes cada vez que é chamado.

No entanto, não posso responder como o compilador trabalha com métodos const. Ouvi dizer que ele pode otimizar certas coisas, embora eu teria que procurá-lo para ter certeza.

No.

Um método const é um método que não altera o estado do objeto (ou seja, seus campos), mas você não pode assumir que, dada a mesma entrada, valor de retorno de um método const é determinado. Em outras palavras, palavra-chave const não implica que a função é um-para-um. Por exemplo, um método que retorna o tempo atual é um método const, mas o seu valor altera ida e volta entre chamadas.

A palavra-chave const em uma função membro marcas a este parâmetro como constante. A função pode dados globais ainda mudo (por isso não pode ser armazenada em cache), mas não dados de objeto (permitindo chamadas em objetos const).

Neste contexto, um const meios de função de membro que this é tratada como um apontador const também. Em termos práticos, isso significa que você não tem permissão para modificar o estado de this dentro de uma função membro const.

Para não-side-effect funções (isto é, o que você está tentando alcançar), GCC tem um "atributo função" chamada pure (você usá-lo, dizendo __attribute__((pure))): http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

Eu duvido, a função pode ainda chamar uma função global que alterou o estado do mundo e não violar const.

Em cima do fato de que a função de membro pode modificar os dados globais, é possível que a função de membro para modificar membros mutáveis ??explicitamente declarados do objeto em questão.

Corey é correto, mas tenha em mente que nenhum membro variáveis ??que são marcados como mutável pode ser modificado de funções membro const.

Isso também significa que essas funções podem ser chamados de outras funções const, ou através de outras referências const.


Edit: Porra, foi espancado por 9 segundos .... 9 !!! :)

métodos const também estão autorizados a modificar os locais estáticos. Por exemplo, o seguinte é (chamadas e repetidas para bar () irá retornar valores crescentes - não um cache 0) perfeitamente legais:

class Foo
{
public:
    int bar() const
    {
        static int x = 0;
        return x++;
    }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top