O que significa o modificador constante após uma declaração de método - página 6

 
Métodos constantes
Os métodos constantes se distinguem pelo fato de que não alteram os valores de seus campos de classe. Vejamos um exemplo chamado CONSTFU:
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

Um método normal nãoFunc() pode alterar o valor do campo alfa, mas um método constante conFunc() não pode. Se for feita uma tentativa de mudar o campo alfa, o compilador relatará um erro.
Para fazer de uma função uma constante, a palavra-chave const deve ser especificada após o protótipo da função, mas antes do início do corpo da função. Se a declaração de função e a definição forem separadas, o modificador de constância deve ser especificado duas vezes - tanto na declaração de função como em sua definição. Faz sentido fazer constante esses métodos, que só lêem dados do campo de classe, porque eles não precisam alterar os valores dos campos de objetos de classe.

O uso de funções constantes ajuda o compilador a detectar erros e também informa ao leitor da listagem que a função não altera os valores dos campos de objeto. Funções constantes podem ser usadas para criar e usar objetos constantes, como veremos mais adiante.

Um exemplo da classe de distância

A fim de não incluir muitas inovações em um único programa, até agora não usamos métodos constantes em nossos exemplos. Entretanto, existem algumas situações em que o uso de métodos constantes seria útil. Por exemplo, o método showdist() da classe Distância, que aparece repetidamente em nossos exemplos, deveria ter sido feito constante porque não muda (e não deveria!) os campos do objeto para o qual é chamado. O objetivo é apenas exibir os valores atuais dos campos na tela.

...

retirado da p. 250, Lafauré R. - Programação orientada a objetos em C++ (4ª ed.) 2004

 
Dmitry Fedoseev:

Isto é o que se quer dizer, porque neste contexto, não se está falando do tipo. A "classe própria" é obviamente sua própria instância (ou seja, objeto).

O membro_x pertence à mesma classe que o método da barra.

C obj._x - aqui o membro _x está em uma obj. de classe estrangeira.

Parece-me aceitável falar de uma classe em vez de uma instância, porque é óbvio que _x pertence à nossa classe, que escrevemos, e obj.x à classe estrangeira, com a qual lidamos.

Falando em terminologia OOP, a terminologia completa aqui é um pouco disso (ou até mesmo muito).

Dmitry, você entende que se você falar dessa maneira, aqueles que começarem a se familiarizar com o OOP com tal terminologia pela primeira vez, ficarão loucos!

É isso que você quer dizer porque não estamos falando de um tipo neste contexto. "Sua classe" é obviamente sua própria instância (ou seja, objeto).

É provavelmente óbvio para você. Estou lendo e me perguntando como um membro _x pode pertencer a uma classe se a classe é uma instrução, uma abstração, como você mesmo disse:

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

O que significa modificador constante após declaração do método?

Dmitry Fedoseev, 2016.02.01 19:06

Como um objeto pode chamar um método? Um método pode ser chamado a partir de uma função ou de outro método.

Não é apenas um método de classe que é chamado, mas um método de um objeto específico. A classe em si é uma abstração.

C obj._x - aqui o membro _x está em uma obj. de classe estranha.

Você realmente não entende a diferença entre uma classe e uma instância de uma classe!? Você não pode dizer isso, de forma alguma, porque isso fará o cérebro do leitor explodir, e ele pensará que o objeto que chamou o método e o objeto objeto são instâncias de classes diferentes, embora sejam instâncias da mesma classe (no exemplo que você citou).

Se falamos da terminologia OOP, toda a terminologia aqui é um pouco disso (ou mesmo muito).

A terminologia é "um pouco de coisa" quando você não entende com o que está lidando. Você só precisa entender claramente o que é uma classe (instrução) e o que é um objeto (instância) de uma classe. E então, muitos problemas desaparecerão por si mesmos. Obviamente, não serei capaz de mudar sua opinião, portanto, não vejo nenhum sentido em continuar a discussão sobre este assunto. É uma pena.
 
unreal:
Métodos constantes
Os métodos constantes se distinguem pelo fato de que não alteram os valores de seus campos de classe. Vejamos um exemplo chamado CONSTFU:
// constfu.cpp
// применение константных методов
class aClass
{
private:
    int alpha;
public:
    void nonFunc()    // неконстантный метод
    { 
        alpha = 99;
    }      // корректно
    void conFunc()const   // константный метод
    { 
        alpha = 99;
    }    // ошибка: нельзя изменить значение поля
};

Um método normal nãoFunc() pode alterar o valor do campo alfa, mas um método constante conFunc() não pode. Se for feita uma tentativa de mudar o campo alfa, o compilador relatará um erro.
Para fazer de uma função uma constante, a palavra-chave const deve ser especificada após o protótipo da função, mas antes do início do corpo da função. Se a declaração de função e a definição forem separadas, o modificador de constância deve ser especificado duas vezes - tanto na declaração de função como em sua definição. Faz sentido fazer constante esses métodos, que só lêem dados do campo de classe, porque eles não precisam alterar os valores dos campos de objetos de classe.

O uso de funções constantes ajuda o compilador a detectar erros e também informa ao leitor da listagem que a função não altera os valores dos campos de objeto. Funções constantes podem ser usadas para criar e usar objetos constantes, como veremos mais adiante.

Um exemplo da classe de distância

A fim de não incluir muitas inovações em um único programa, até agora não usamos métodos constantes em nossos exemplos. Entretanto, existem algumas situações em que o uso de métodos constantes seria útil. Por exemplo, o método showdist() da classe Distância, que aparece repetidamente em nossos exemplos, deveria ter sido feito constante porque não muda (e não deveria!) os campos do objeto para o qual é chamado. O objetivo é apenas exibir os valores atuais dos campos na tela.

...

retirado da p. 250, Lafauré R. - Programação orientada a objetos em C++ (4ª ed.) 2004

Mas que ordem estará em sua mente se mesmo em um livro sobre o OOP eles escreverem certo ou errado. Embora, talvez, seja a tradução.
 
Alexey Kozitsyn:

Dmitry, você entende que se você falar assim, aqueles que começarem a se familiarizar com o OOP com tal terminologia pela primeira vez, ficarão loucos?

É provavelmente óbvio para você. Estou lendo e pensando como um membro _x pode pertencer a uma classe, se uma classe é uma instrução, uma abstração, como você mesmo disse:

Você realmente não entende a diferença entre uma classe e uma instância de uma classe!? Você não pode dizer isso, de forma alguma, porque isso causará uma explosão cerebral no leitor e ele pensará que o objeto que chamou o método e o objeto objeto são instâncias de classes diferentes, embora sejam instâncias da mesma classe (no exemplo que você deu).

A terminologia é então "um pouco disso" quando você não entende com o que está lidando. Você só precisa entender claramente o que é uma classe (instrução) e o que é um objeto (instância) de uma classe. E então, muitos problemas desaparecerão por si mesmos. Obviamente, não serei capaz de mudar sua opinião, portanto, não vejo nenhum sentido em continuar a discussão sobre este assunto. É uma pena.

Por que você deveria mudar minha opinião? Mudar sua opinião sobre o quê? Por mim está tudo bem. O primeiro posto desta linha foi suficiente para que eu tivesse um entendimento completo e sem conflitos.

Observe também que foi você quem escreveu que a referência seria suficiente para entender. Então não está nada claro sobre o que você está discutindo?

ps. Não me atribua um monte de seus próprios delírios.

 
George Merts:

Pessoalmente, sempre entendi os métodos constantes como métodos que não podem mudar as variáveis de classe.

Eu os usei muito raramente, porque muitas vezes encontrei uma situação em que uma redefinição de método requer a mudança de algo, enquanto o método básico é constante (já foi mencionado aqui).

Os métodos estáticos são amplamente utilizados. Em quase todas as classes complexas. Normalmente são métodos adicionais que "servem" e não requerem acesso às variáveis de classe.

Além disso, para constantes como "número de segundos em um dia", eu tento usar uma construção const estática em vez de #define. Neste caso, a declaração e inicialização de tal constante estão em locais diferentes, mas o controle de tipo ocorre e me ajuda mais de uma vez.

O mesmo que eu raramente uso. Na verdade, comecei o tópico porque um dos participantes deste fórum me perguntou em uma mensagem particular por que eu precisava deles.
 
George Merts:

Pessoalmente, sempre entendi os métodos constantes como métodos que não podem mudar as variáveis de classe.

Eu os usei muito raramente, porque me deparei repetidamente com uma situação em que um método precisa mudar algo, e o método básico é constante (já mencionei isso aqui).

Você NÃO os usa por esse motivo, e eu os uso por esse motivo:

zaskok3:

Para mim, o uso de constante e estático aumenta muito a legibilidade/entendimento de meu próprio código. E permite que você pegue com freqüência bugs ou falhas em sua própria arquitetura logo no início de sua implementação.


Escrevo tudo apenas para mim mesmo. E parece que eu não vou mudar alguns dados que não deveria de qualquer forma. Mas o desejo de me proteger de minha própria estupidez me faz rebitear a arquitetura OOP de tal forma, que somente o que deve ser acessível para mudar. O resto não é. E aqui os tipos const + inheritance são de grande ajuda. Eu o recomendo.
 

Pessoas gentis ajudam na compilação da EA, por favor, eu não sou bom em programação.

Este é o erro que eu recebo ao compilar 'apagar' - nome esperado

O erro no código é destacado em vermelho

apagar (tipo int){

if(OrdersTotal()>0){

for(i=OrdensTotal()-1;i>=0;i--){

OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

if(type!=6 && type!=7 && type!=8)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==type)OrderDelete(OrderTicket();

if(type===6)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP || OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLLIMIT)OrderDelete(OrderTicket());

if(type===7)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)OrderDelete(OrderTicket());

if(type===8)if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLLIMIT)OrderDelete(OrderTicket());

}

}

}


Aqui está outro erro "(' - apontador de objeto esperado

if(oppositedelete){delete(OP_SELLSTOP);delete(OP_SELLLIMIT);}

E aqui '}'... - nem todos os caminhos de controle retornam um valor

int countglobal(){

int cnt=0;

if(OrdersTotal()>0){

for(i=OrdensTotal()-1;i>=0;i--){

OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

cnt++;

}

retorno(cnt);

}

}

 
zaskok3:

Você NÃO os usa por este motivo, e eu os uso por este motivo:

Concordo que o especificador const é útil ao ler e compreender funções escritas longas. Mas restringir o acesso às variáveis me parece fazer mais sentido declarando-as em diferentes seções privadas-protegidas-públicas (eu pessoalmente nunca declaro variáveis como públicas, apenas métodos).

É difícil para mim pensar em uma situação em que uma variável de classe interna não deve ser modificada nos descendentes.

 
Anton Razmyslov:

Pessoas amáveis ajudam na compilação da EA muito por favor, não são boas em programação.

E na lógica? Por que desorganizar um tópico não-profile com perguntas como esta?
 

A propósito, ninguém escreveu que o modificador Const Const não só não permite alterar dados dentro da própria classe, mas até mesmo abordar métodos não constantes. Um exemplo simples: há uma classe de posição, precisamos ordenar a lista de posições por lucro. O lucro é calculado pelo pedido:

class CPosition : public CObject
{
private:
   double m_profit;
   void CalculateProfit()
   {
      m_profit = 31337;
   }
public:
   CPosition(void) : m_profit(0.0)
   {
   }
   double Profit(void)const
   {
      if(m_profit == 0.0)
         CalculateProfit(); // <- Константный метод вызывает блок рассчета и вызывает ошибку
      return m_profit;
   }
   virtual int Compare(const CObject *node,const int mode=0) const
   {
      const CPosition* pos = node;
      if(pos.Profit() > Profit())
         return 1;
      else if(pos.Profit() < Profit())
         return -1;
      return 0;
   }
};

Este código causará um erro porque embora o método Lucro seja constante, refere-se ao método não-constante CalcultaeProfit se o lucro ainda não foi calculado.

Note que o próprio método Profit é absolutamente seguro: ele garante que o valor que devolve não está vazio. Entretanto, o método constante exige o abandono dos cálculos nos bastidores e a alta segurança do código em favor de algumas construções fora da caixa que não sabem o que e por que eles limitam.