Declarações e definições (C++)
Um programa C++ consiste em várias entidades, como variáveis, funções, tipos e namespaces. Cada uma dessas entidades deve ser declarada antes que possa ser usada. Uma declaração especifica um nome exclusivo para a entidade, junto às informações sobre seu tipo e outras características. No C++, o ponto em que um nome é declarado é o ponto em que ele fica visível para o compilador. Você não pode se referir a uma função ou classe declarada posteriormente na unidade de compilação. As variáveis devem ser declaradas o mais próximo possível antes do ponto em que são usadas.
O exemplo a seguir mostra algumas declarações:
#include <string>
int f(int i); // forward declaration
int main()
{
const double pi = 3.14; //OK
int i = f(2); //OK. f is forward-declared
C obj; // error! C not yet declared.
std::string str; // OK std::string is declared in <string> header
j = 0; // error! No type specified.
auto k = 0; // OK. type inferred as int by compiler.
}
int f(int i)
{
return i + 42;
}
namespace N {
class C{/*...*/};
}
Na linha 5, a função main
é declarada. Na linha 7, uma variável const
nomeada pi
é declarada e inicializada. Na linha 8, um inteiro i
é declarado e inicializado com o valor produzido pela função f
. O nome f
está visível para o compilador devido à declaração antecipada na linha 3.
Na linha 9, uma variável nomeada obj
do tipo C
é declarada. No entanto, essa declaração gera um erro porque C
não é declarada até o final do programa e não é declarada antecipadamente. Para corrigir o erro, você pode mover toda a definição de C
antes de main
ou então adicionar uma declaração antecipada para ele. Esse comportamento é diferente de outras linguagens, como C#. Nessas linguagens, as funções e as classes podem ser usadas antes do ponto de declaração em um arquivo de origem.
Na linha 10, uma variável nomeada str
do tipo std::string
é declarada. O nome std::string
é visível porque foi introduzido no string
arquivo de cabeçalho, que é mesclado no arquivo fonte na linha 1. std
é o namespace no qual a classe string
é declarada.
Na linha 11, um erro é gerado porque o nome j
não foi declarado. Uma declaração deve fornecer um tipo, ao contrário de outras linguagens, como JavaScript. Na linha 12, é usada a palavra-chave auto
, que diz ao compilador para inferir o tipo de k
com base no valor com o qual é inicializado. Nesse caso, o compilador escolhe int
para o tipo.
Escopo de declaração
O nome introduzido por uma declaração é válido dentro do escopo em que a declaração ocorre. No exemplo anterior, as variáveis declaradas dentro da função main
são variáveis locais. Você pode declarar outra variável nomeada i
fora da principal, no escopo global, que será uma entidade separada. No entanto, essa duplicação de nomes pode levar a erros e confusão do programador e deve ser evitada. Na linha 21, a classe C
é declarada no escopo do namespace N
. O uso de namespaces ajuda a evitar colisões de nomes. A maioria dos nomes da Biblioteca Padrão do C++ são declarados dentro do namespace std
. Para obter mais informações sobre como as regras de escopo interagem com as declarações, consulte Escopo.
Definições
Algumas entidades, incluindo funções, classes, enumerações e variáveis constantes, devem ser definidas, bem como declaradas. Uma definição fornece ao compilador todas as informações necessárias para gerar o código do computador quando a entidade for usada posteriormente no programa. No exemplo anterior, a linha 3 contém uma declaração para a função f
, mas a definição da função é fornecida nas linhas 15 a 18. Na linha 21, a classe C
é declarada e definida (embora, conforme definido, a classe não faça nada). Uma variável constante deve ser definida, em outras palavras, atribuída a um valor, na mesma instrução na qual é declarada. Uma declaração de um tipo interno como int
é automaticamente uma definição porque o compilador sabe quanto espaço alocar para ele.
O exemplo a seguir mostra declarações que também são definições:
// Declare and define int variables i and j.
int i;
int j = 10;
// Declare enumeration suits.
enum suits { Spades = 1, Clubs, Hearts, Diamonds };
// Declare class CheckBox.
class CheckBox : public Control
{
public:
Boolean IsChecked();
virtual int ChangeState() = 0;
};
Seguem algumas declarações que não são definições:
extern int i;
char *strchr( const char *Str, const char Target );
Typedefs e usando instruções
Em versões mais antigas do C++, a palavra-chave typedef
é usada para declarar um novo nome que é um alias para outro nome. Por exemplo, o tipo std::string
é outro nome para std::basic_string<char>
. Deve ser óbvio por que os programadores usam o nome typedef e não o nome real. No C++ moderno, a palavra-chave using
tem preferência sobre typedef
, mas a ideia é a mesma: um novo nome é declarado para uma entidade, que já está declarada e definida.
Membros de classes estáticas
Os membros de dados de classes estáticas são variáveis discretas compartilhadas por todos os objetos da classe. Como elas são compartilhadas, elas devem ser definidas e inicializadas fora da definição de classe. Para obter mais informações, consulte Classes.
declarações externas
Um programa C++ pode conter mais de uma unidade de compilação. Para declarar uma entidade definida em uma unidade de compilação separada, use a palavra-chave extern
. As informações na declaração são suficientes para o compilador. No entanto, se a definição da entidade não puder ser encontrada na etapa de vinculação, o vinculador gerará um erro.
Nesta seção
Classes de armazenamento
const
constexpr
extern
Inicializadores
Aliases e typedefs
using
declaração
volatile
decltype
Atributos em C++