AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79349442
Accepted
user22481460
user22481460
Asked: 2025-01-12 14:22:46 +0800 CST2025-01-12 14:22:46 +0800 CST 2025-01-12 14:22:46 +0800 CST

é a mesma tabela virtual entre o objeto da classe base e o objeto da classe derivada?

  • 772

As classes base e derivadas compartilham uma tabela virtual? Quando me candidatei a um emprego, alguns entrevistadores de empresas famosas da Internet disseram que sim com certeza. Embora eu tenha dito a eles que o valor do ponteiro apontando para a tabela virtual no objeto da classe derivada é diferente do valor do ponteiro apontando para a tabela virtual no objeto da classe base, então eles não devem compartilhar a mesma tabela virtual, o entrevistador ainda disse com certeza que eles compartilham a mesma tabela virtual. Então, fiquei um pouco confuso e vim aqui para encontrar a resposta.

c++
  • 4 4 respostas
  • 115 Views

4 respostas

  • Voted
  1. Best Answer
    Ted Lyngmo
    2025-01-12T14:22:55+08:002025-01-12T14:22:55+08:00

    Pode depender da implementação, mas pelo menos nem o gcc nem o clang deixam a classe base e as classes derivadas compartilharem vtable. Haverá uma vtable por classe (que é então compartilhada entre todas as instâncias da classe). Isso derrotaria o propósito de implementar polimorfismo de tempo de execução usando vtables se não houvesse uma vtable por classe.

    • 7
  2. Sebastian Redl
    2025-01-12T15:10:03+08:002025-01-12T15:10:03+08:00

    Claro que é um problema de implementação, mas a menos que você desabilite o RTTI, as classes base e derivadas não podem ter vptrs idênticos, já que eles também são usados ​​para typeide dynamic_cast, e as classes simplesmente não se comportam da mesma forma.

    Para compartilhar uma vtable, então, eles teriam que ter vtable ptrs e typeinfo ptrs separados (uma sobrecarga de ponteiro adicional por objeto , o que seria uma péssima escolha de implementação) ou fazer com que o vptr apontasse para um objeto typeinfo que é por classe, e então fazer com que ele contivesse o ponteiro para uma vtable compartilhada, o que significaria outro nível de indireção para chamadas de funções virtuais, o que é outra péssima escolha de implementação.

    Nenhuma implementação sensata compartilhará vtables.

    • 2
  3. JaMiT
    2025-01-12T16:48:13+08:002025-01-12T16:48:13+08:00

    o valor do ponteiro que aponta para a tabela virtual no objeto da classe derivada é diferente do valor do ponteiro que aponta para a tabela virtual no objeto da classe base

    Este é um lugar onde os detalhes da língua inglesa importam, e falantes não nativos podem sofrer aqui. (No Staging Ground, ficou bem claro que o autor não é nativo. Felizmente, a questão foi esclarecida.) Talvez tenha havido alguma falha de comunicação durante a entrevista? Em particular, estou olhando para "no objeto da classe base", que não está bem formulado. Quando a formulação está um pouco errada, as pessoas tendem a presumir uma correção. No entanto, neste caso, vejo duas correções possíveis, que infelizmente levam a duas questões bem diferentes.

    Se você mudar "the" para "a", então a comparação é entre o ponteiro em um objeto de classe derivada e aquele em um objeto de classe base (não um subobjeto). Dessa perspectiva, a questão é se uma classe base e uma classe derivada podem ou não compartilhar uma tabela de função virtual. Ou seja, pode haver uma vtable para ambas as classes?

    Se você alterar "objeto" para "subobjeto", a comparação será sobre dois ponteiros em um único objeto. Cada objeto de classe derivada contém um subobjeto de classe base. O subobjeto de classe base precisa conter um ponteiro para uma vtable para que funções virtuais possam ser invocadas por meio de um ponteiro para a classe base. Da mesma forma, o objeto de classe derivada também deve conter um ponteiro para uma vtable. Dessa perspectiva, a questão é se esses dois ponteiros devem ou não ter o mesmo valor. Ou seja, existe uma vtable para esse objeto?

    Classes e (múltiplas) vtables

    Embora a implementação de vtables não seja padronizada, normalmente cada classe terá sua própria tabela de funções virtuais. A classe base terá uma, e a classe derivada terá uma diferente. Normalmente, haverá duas vtables, uma para cada classe.

    Teoricamente, porém, isso não precisa ser o caso. Se a classe derivada não sobrescrever nenhuma função, as vtables para as classes base e derivada podem ser idênticas. Além disso, se as informações do tipo de tempo de execução forem suprimidas (o que pode limitar as capacidades de dynamic_cast), é plausível que o compilador possa otimizar essas duas tabelas em uma.

    Tenha em mente que a teoria é uma otimização para um caso bastante especial. E não sei se ela é realmente implementada. Então, é razoável concluir que classes diferentes têm vtables diferentes, pelo menos em qualquer caso em que isso importe.

    Um objeto e sua (uma) vtable

    Dentro de um objeto, uma classe derivada frequentemente usa o ponteiro de tabela virtual que já está presente no subobjeto da classe base. Devido ao arranjo inteligente da tabela, a classe base pode olhar para a tabela para uma classe derivada e "ver" apenas a parte que se aplica à classe base. (Isso é semelhante a como um ponteiro para base pode apontar para um objeto derivado e "ver" apenas o subobjeto da classe base.) Neste cenário, os valores dos vpointers são os mesmos porque há apenas um vpointer.

    Em casos mais complexos, pode haver mais de um ponteiro de tabela virtual em um objeto, especialmente no caso de herança múltipla (ou seja, uma classe com várias classes base, em oposição a uma classe cuja classe base tem uma classe base). Se houver várias classes base com funções virtuais, cada uma precisa de seu próprio ponteiro de tabela virtual. Além disso, é praticamente impossível que esses vpointers tenham o mesmo valor, pois cada classe base determina independentemente como sua vtable é estruturada. Portanto, o vpointer da classe derivada não pode ter o mesmo valor que cada vpointer da classe base. (Ele corresponderá a um deles, no entanto, pelo menos nas implementações que conheço.)

    Entretanto, mesmo que os vpointers das classes base sejam diferentes, ainda há apenas uma vtable para o objeto. Pense na classe derivada vtable como consistindo de funções da classe base 1, seguidas por funções da classe base 2, etc. Cada subobjeto da classe base teria um vpointer para sua porção da tabela da classe derivada. Então, em princípio, os vpointers apontam para a mesma tabela, apenas com deslocamentos diferentes.

    Em resumo, para um dado objeto, há apenas uma tabela de funções virtuais. A classe derivada e uma de suas classes base concordarão com o endereço desta tabela. Se houver outras classes base, seus vpointers serão deslocados daquele da classe derivada, mas ainda apontarão para a mesma tabela.

    • 2
  4. gnasher729
    2025-01-12T15:22:36+08:002025-01-12T15:22:36+08:00

    Se você não tiver substituído um único método, as tabelas serão idênticas e, portanto, compartilhadas.

    Se você tiver substituído qualquer coisa, mas adicionado mais métodos virtuais na classe derivada, então a classe base poderia usar o início da vtable das classes derivadas. E tudo isso somente se a vtable for usada somente para despacho de método.

    Caso contrário, as vtables devem ser diferentes.

    • 1

relate perguntas

  • Por que os compiladores perdem a vetorização aqui?

  • Erro de compilação usando CMake com biblioteca [fechada]

  • Erro lançado toda vez que tento executar o premake

  • Como criar um tipo de octeto semelhante a std::byte em C++?

  • Somente operações bit a bit para std::byte em C++ 17?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve