Sou um desenvolvedor JAVA que está tentando aprender C ++, mas não sei realmente qual é a prática recomendada para declarações de função padrão.
Na aula:
class Clazz
{
public:
void Fun1()
{
//do something
}
}
Ou fora:
class Clazz
{
public:
void Fun1();
}
Clazz::Fun1(){
// Do something
}
Tenho a sensação de que o segundo pode ser menos legível ...
.cpp
arquivo separado .inline
.inline
apenas relaxa a regra de uma definição, que é necessária se outra unidade de tradução usarClazz
Respostas:
C ++ é orientado a objetos, no sentido de que suporta o paradigma orientado a objetos para o desenvolvimento de software.
No entanto, diferentemente de Java, C ++ não força você a agrupar definições de função em classes: a maneira padrão do C ++ para declarar uma função é apenas declarar uma função, sem nenhuma classe.
Se, em vez disso, você estiver falando sobre declaração / definição de método, a maneira padrão é colocar apenas a declaração em um arquivo de inclusão (normalmente denominado
.h
ou.hpp
) e a definição em um arquivo de implementação separado (normalmente denominado.cpp
ou.cxx
). Eu concordo que isso é realmente um pouco chato e requer algumas duplicações, mas é como a linguagem foi projetada.Para experimentos rápidos e projetos de arquivo único, qualquer coisa funcionaria ... mas para projetos maiores, essa separação é praticamente necessária.
Nota: Mesmo se você conhece Java, C ++ é uma linguagem completamente diferente ... e é uma linguagem que não pode ser aprendida experimentando. A razão é que é uma linguagem bastante complexa com muitas assimetrias e escolhas aparentemente ilógicas e, o mais importante, quando você comete um erro, não há "anjos de erro em tempo de execução" para salvá-lo como em Java ... mas há " daemons de comportamento indefinido ".
A única maneira razoável de aprender C ++ é lendo ... não importa o quão inteligente você seja, não há como você adivinhar o que o comitê decidiu (na verdade, ser inteligente às vezes é até um problema porque a resposta correta é ilógica e uma consequência do histórico herança.)
Escolha um ou dois bons livros e leia-os de capa a capa.
fonte
O primeiro define sua função de membro como uma função embutida , enquanto a segunda não. A definição da função, neste caso, reside no próprio cabeçalho.
A segunda implementação colocaria a definição da função no arquivo cpp.
Ambos são semanticamente diferentes e não é apenas uma questão de estilo.
fonte
A definição da função é melhor fora da classe. Dessa forma, seu código pode permanecer seguro, se necessário. O arquivo de cabeçalho deve apenas fornecer declarações.
Suponha que alguém queira usar seu código, você pode simplesmente fornecer a ele o arquivo .h e o arquivo .obj (obtido após a compilação) de sua classe. Ele não precisa do arquivo .cpp para usar seu código.
Dessa forma, sua implementação não ficará visível para ninguém.
fonte
O método "Dentro da classe" (I) faz o mesmo que o método "fora da classe" (O).
No entanto, (I) pode ser usado quando uma classe é usada apenas em um arquivo (dentro de um arquivo .cpp). (O) é usado quando está em um arquivo de cabeçalho. Os arquivos cpp são sempre compilados. Arquivos de cabeçalho são compilados quando você usa #include "header.h".
Se você usar (I) em um arquivo de cabeçalho, a função (Fun1) será declarada toda vez que você incluir #include "header.h". Isso pode levar à declaração da mesma função várias vezes. Isso é mais difícil de compilar e pode até levar a erros.
Exemplo para uso correto:
Arquivo1: "Clazz.h"
Arquivo2: "Clazz.cpp"
Arquivo 3: "UseClazz.cpp"
Arquivo 4: "AlsoUseClazz.cpp"
Arquivo 5: "DoNotUseClazzHeader.cpp"
fonte
As funções de membro podem ser definidas dentro da definição de classe ou separadamente usando o operador de resolução de escopo, ::. Definir uma função de membro dentro da definição de classe declara a função embutida, mesmo se você não usar o especificador embutido. Portanto, você pode definir a função Volume () conforme abaixo:
Se desejar, você pode definir a mesma função fora da classe usando o operador de resolução de escopo, :: como segue
Aqui, o único ponto importante é que você teria que usar o nome da classe antes de :: operador. Uma função de membro será chamada usando um operador ponto (.) Em um objeto onde manipulará dados relacionados a esse objeto apenas da seguinte maneira:
(em: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ), ambas as formas são legais.
Não sou um especialista, mas acho que, se você colocar apenas uma definição de classe em um arquivo, isso realmente não importa.
mas se você aplicar algo como classe interna, ou tiver várias definições de classe, a segunda será difícil de ler e manter.
fonte
O primeiro deve ser colocado no arquivo de cabeçalho (onde reside a declaração da classe). O segundo pode estar em qualquer lugar, seja no cabeçalho ou, normalmente, em um arquivo de origem. Na prática, você pode colocar pequenas funções na declaração da classe (que as declara implicitamente inline, embora seja o compilador que decide se elas serão inline ou não). No entanto, a maioria das funções tem uma declaração no cabeçalho e a implementação em um arquivo cpp, como em seu segundo exemplo. E não, não vejo nenhuma razão para que isso seja menos legível. Sem mencionar que você pode realmente dividir a implementação de um tipo em vários arquivos cpp.
fonte
Uma função definida dentro de uma classe é tratada por padrão como uma função embutida. Uma razão simples pela qual você deve definir sua função externamente:
Um construtor da classe verifica as funções virtuais e inicializa um ponteiro virtual para apontar para a VTABLE adequada ou a tabela de método virtual , chama o construtor da classe base e inicializa as variáveis da classe atual, de modo que realmente faz algum trabalho.
As funções inline são usadas quando as funções não são tão complicadas e evitam a sobrecarga da chamada da função. (A sobrecarga inclui um salto e uma ramificação no nível do hardware.) E, conforme descrito acima, o construtor não é tão simples de ser considerado como embutido.
fonte