Na marcação C ++, uma função de membro const
significa que ela pode ser chamada em const
instâncias. Java não tem um equivalente a isso. Por exemplo:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Os valores podem ser atribuídos, uma vez, posteriormente em Java, por exemplo:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
é legal em Java, mas não em C ++, enquanto que:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Tanto em Java quanto em C ++, as variáveis de membro podem ser final
/ const
respectivamente. Eles precisam receber um valor no momento em que uma instância da classe termina de ser construída.
Em Java, eles devem ser definidos antes da conclusão do construtor, isso pode ser alcançado de uma de duas maneiras:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
No C ++, você precisará usar as listas de inicialização para fornecer aos const
membros um valor:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Em Java, final pode ser usado para marcar as coisas como não substituíveis. C ++ (pré-C ++ 11) não faz isso. Por exemplo:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Mas em C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
isso é bom, porque a semântica de marcar uma função de membro const
é diferente. (Você também pode sobrecarregar tendo apenas const
uma das funções de membro. (Observe também que o C ++ 11 permite que as funções de membro sejam marcadas como finais, consulte a seção de atualização do C ++ 11)
Atualização do C ++ 11:
De fato, o C ++ 11 permite marcar classes e funções-membro como final
, com semântica idêntica ao mesmo recurso em Java, por exemplo, em Java:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Agora pode ser escrito exatamente em C ++ 11 como:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Eu tive que compilar este exemplo com um pré-lançamento do G ++ 4.7. Observe que isso não substitui const
nesse caso, mas aumenta, fornecendo o comportamento semelhante ao Java que não foi visto com a palavra-chave C ++ equivalente mais próxima. Portanto, se você quisesse que uma função membro fosse ambas final
e const
você faria:
class Bar {
public:
virtual void foo() const final;
};
(A ordem de const
e final
aqui é obrigatória).
Anteriormente, não havia um equivalente direto de const
funções-membro, embora tornar as funções não- virtual
seria uma opção em potencial, sem causar um erro no tempo de compilação.
Da mesma forma que o Java:
public final class Bar {
}
public class Error extends Bar {
}
torna-se em C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Anteriormente, os private
construtores eram provavelmente o mais próximo possível disso em C ++)
Curiosamente, para manter a compatibilidade com versões anteriores ao código pré-C ++ 11 final
não é uma palavra-chave da maneira usual. (Pegue o exemplo trivial e legal do C ++ 98 struct final;
para ver por que torná-lo uma palavra-chave quebraria o código)