Para entender conceitos simples em C++, como métodos de uma classe, ajuda muito seguir o raciocínio dos programadores C e como eles lidavam com o tipo de problema que C++ resolve elegantemente implementando um novo compilador com uma nova linguagem. Tomemos, por exemplo, métodos. Um método é uma função chamada dentro de um contexto. Qual o contexto? O objeto. Ou seja, uma instância específica de uma classe, que é um molde para se fazer alguma coisa.
int main()
{
MinhaClasse obj;
obj.MeuMetodo(); // o contexto é obj, uma instância de MinhaClasse
}
Para obter esse contexto, existe uma palavra-chave reservada dentro dos métodos que é o this, que está tão incrustado na linguagem que não precisa ser usado explicitamente: quando referenciamos alguma propriedade (ou um outro método) da classe, só pelo fato de estarmos dentro de um método o compilador já entende que se trata do mesmo objeto, ou mesmo contexto.
class MinhaClasse
{
public:
void MeuMetodo();
void MeuOutroMetodo();
int MinhaPropriedade;
};
void MinhaClasse::MeuMetodo()
{
MinhaPropriedade = 42; // ou seja: this->MinhaPropriedade = 42;
MeuOutroMetodo(); // ou seja: this->MeuOutroMetodo();
}
E contexto nesse sentido nada mais é que um endereço na memória para alguma coisa que nos interessa. Tal qual uma função API do Windows -- tal qual FindFirstFile -- que recebe ou retorna uma struct com o que precisamos, esse geralmente é o contexto procurado.
WIN32_FIND_DATA findData;
HANDLE findH = FindFirstFile("*.txt", &findData);
if( findH != INVALID_HANDLE_VALUE )
{
if( findData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED )
{
//...
No caso de nós, que escrevemos uma "classe", o contexto é recebido "de fora":
HANDLE MyFindFirstFile(const char* pattern, LPWIN32_FIND_DATA findData)
{
//...
findData->dwFileAttributes = FILE_ATTRIBUTE_ENCRYPTED;
//...
Tal como uma struct que definimos, ela vira o contexto. Da mesma forma, um objeto de uma classe em C++ é esse contexto. Podemos fazer a mesma coisa em C, com o trabalho adicional de especificar o "this" (isto é, o ponteiro para o contexto/struct):
struct MinhaClasse
{
int MinhaPropriedade;
};
void MinhaClasse_MeuMetodo(MinhaClasse* pThis)
{
pThis->MinhaPropriedade = 42;
///@todo Chamar pThis->MeuOutroMetodo();
}
Em um próximo post vamos ver como fazer para chamar MeuOutroMetodo a partir de uma estrutura em C.