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 é introduzido no stringarquivo de cabeçalho, que é mesclado ao arquivo de origem 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++

Confira também

Conceitos básicos