Por que 'this' é um ponteiro e não uma referência?

183

Eu estava lendo as respostas para esta pergunta, prós e contras do C ++, e tive essa dúvida ao ler os comentários.

os programadores freqüentemente acham confuso que "isto" seja um ponteiro, mas não uma referência. Outra confusão é por que "hello" não é do tipo std :: string, mas é avaliado como um caractere const * (ponteiro) (após a conversão de matriz em ponteiro) - Johannes Schaub - litb 22/08/08 às 1:56

Isso mostra apenas que ele não usa as mesmas convenções que outros idiomas (posteriores). - le dorfier 22/12/08 às 3:35

Eu chamaria a coisa "isto" de uma questão bastante trivial. Epa, obrigado por detectar alguns erros nos meus exemplos de comportamento indefinido. :) Embora eu não entenda que informação sobre tamanho tem a ver com qualquer coisa no primeiro. Um ponteiro simplesmente não tem permissão para apontar para fora da memória alocada - jalf

Isso é constante? - yesraaj 22/12/08 às 6:35

isso pode ser constante se o método for const int getFoo () const; <- no escopo de getFoo, "isto" é constante e, portanto, é somente leitura. Isso evita bugs e fornece algum nível de garantia ao chamador de que o objeto não será alterado. - Doug T. 22/12/08 às 16:42

você não pode reatribuir "isso". ou seja, você não pode fazer "this = & other;", porque este é um rvalue. mas isso é do tipo T *, não do tipo T const. ou seja, é um ponteiro não constante. se você estiver em um método const, é um ponteiro para const. T const. mas o ponteiro em si é inconstante - Johannes Schaub - litb Dec 22 '08 às 17:53

pense em "this" assim: #define this (this_ + 0) onde o compilador cria "this_" como um ponteiro para o objeto e faz "this" uma palavra-chave. você não pode atribuir "this" porque (this_ + 0) é um rvalue. é claro que não é assim (não existe essa macro), mas pode ajudar a entendê-lo - Johannes Schaub - litb Dec 22 '08 às 17:55

Minha pergunta é: por que thisum ponteiro não é uma referência? Algum motivo específico para torná-lo um ponteiro?


Alguns argumentos adicionais sobre por que thisser uma referência faria sentido:

  • Considere Item 1from More Effective C++ : use reference quando for garantido que temos um objeto válido, isto é, não um NULL (minha interpretação).
  • Além disso, as referências são consideradas mais seguras que os ponteiros (porque não podemos estragar a memória com um ponteiro perdido).
  • Terceiro, a sintaxe para acessar as referências ( .) é um pouco melhor e mais curta do que acessar ponteiros ( ->ou (*)).
Naveen
fonte
5
@paulm O que esse "hack" realmente faria? Nem thissempre avalia para true?
IFreilicht
6
@ Paulm Eu não acho que isso seja realmente válido em C ++. A chamada de métodos em um nullptr para um objeto resulta em um comportamento indefinido.
antred
5
@ paulm Talvez funcione em alguns casos, mas imagine se o método fosse virutal. Como uma pesquisa de tabela v pode ser feita sem objeto?
Jason Creighton
3
@paulm Se você o viu no código de produção, abandone o navio! Isso é UB.
Alice
6
Só vou deixar isso aqui ... (de afxwin2.inl do MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

Respostas:

176

Quando o idioma estava evoluindo, nos primeiros lançamentos com usuários reais, não havia referências, apenas indicadores. As referências foram adicionadas quando a sobrecarga do operador foi adicionada, pois requer referências para funcionar de forma consistente.

Um dos usos de thisé para um objeto obter um ponteiro para si mesmo. Se fosse uma referência, teríamos que escrever &this. Por outro lado, quando escrevemos um operador de atribuição, precisamos fazê-lo return *this, o que pareceria mais simples return this. Portanto, se você tivesse uma lousa em branco, poderia argumentar de qualquer maneira. Mas o C ++ evoluiu gradualmente em resposta ao feedback de uma comunidade de usuários (como as coisas mais bem-sucedidas). O valor da compatibilidade com versões anteriores supera totalmente as pequenas vantagens / desvantagens decorrentes de thisser uma referência ou um ponteiro.

Daniel Earwicker
fonte
4
Bem, também é frequentemente útil para um objeto obter uma referência a si mesmo. Eu diria que é um uso mais comum. Enfim, o principal motivo é como você disse, as referências não existiam quando eles criaram o ponteiro 'this'.
jalf
20
E, se isso fosse uma referência, seria difícil sobrecarregar operator &para fazer algo útil. Teria que haver alguma sintaxe especial para obter o endereço disso que não passaria operator &.
Onívoro
10
@conio - você pode querer verificar se da próxima vez que estiver perto de um compilador C ++! :) Algo como:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker
14
Onipresente, você pode escrever &reinterpret_cast<char&>(this);para obter o endereço real para sobrecarga operator&(na verdade, isso é o que boost::addressoffaz).
Johannes Schaub - litb
9
Como realmente não faz sentido thisser nulo, parece-me que uma referência é realmente mais adequada.
Ponkadoodle 02/02/12
114

Um pouco tarde para a festa ... Diretamente da boca do cavalo, eis o que Bjarne Stroustrup tem a dizer (que é essencialmente repetido ou retirado do livro "Design e evolução do C ++"):

Por que é "this " não é uma referência?

Como "this" foi introduzido no C ++ (realmente no C com Classes) antes das referências serem adicionadas. Além disso, eu escolhi " this" seguir o uso do Simula, ao invés do uso (mais tarde) do Smalltalk de "self".

Michael Burr
fonte
2
Sim, o self seria bom por consistência com outras línguas, tudo bem.
pilkch 18/06