"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Por que a inicialização de membros estáticos em classes de modelo se comporta de maneira diferente?

Por que a inicialização de membros estáticos em classes de modelo se comporta de maneira diferente?

Publicado em 2024-11-14
Navegar:197

 Why Does Static Member Initialization in Templated Classes Behave Differently?

Complicações de inicialização de membro estático em classes modeladas

A inicialização de membro estático em C é uma técnica amplamente usada, mas pode se tornar complexa ao lidar com aulas modeladas. Em classes não modeladas, uma estrutura auxiliar aninhada pode ser empregada para inicialização, mas essa abordagem é insuficiente quando a classe envolvente é modelada.

Considere o seguinte exemplo simplificado:

struct A
{
    static std::string mA;
    static InitHelper mInit;

    static const std::string& getA() { return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;


template
struct B
{
    static std::string mB;
    static InitHelper mInit;

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};
template
std::string B::mB;
template
typename B::InitHelper B::mInit;

int main()
{
    std::cout ::getB() ::getHelper(); // [2]
}

Comportamento esperado:

Quando [1] é descomentado e [2] é comentado, esperaríamos que B::mB fosse inicializado como " Olá, sou B.". No entanto, isso não ocorre.

Comportamento real:

  • Com [1] e [2] comentado: Sem efeitos colaterais ocorrer.
  • Com [1] não comentado: B::getB() retorna um vazio string.
  • Com [1] e [2] descomentados: B::mB foi inicializado corretamente.
  • Com [1] comentado e [2] não comentado: Ocorre uma falha de segmentação durante a inicialização estática.

Motivo do Discrepância:

De acordo com o padrão ISO/IEC C 2003, o membro do modelo é instanciado implicitamente quando referenciado em um contexto que requer a existência de sua definição. No entanto, a inicialização do membro de dados estáticos (e quaisquer efeitos colaterais associados) ocorre apenas quando o membro de dados estáticos é usado explicitamente. Isso significa que se um membro do modelo for referenciado apenas em modelos não instanciados ou em outros contextos que não exijam sua instanciação completa, seus membros de dados estáticos não serão inicializados.

No exemplo, B:: getB() requer que B::mB exista, mas isso apenas força a instanciação da declaração do modelo de membro, não sua definição (incluindo o inicializador). Em contraste, B::getHelper() requer a definição de B::mInit porque retorna uma referência a ele.

Solution:

O padrão proíbe que as definições de membros de dados estáticos de modelo de classe explicitamente especializados tenham inicialização ordenada, enquanto outros membros de dados estáticos de modelo de classe tenham inicialização não ordenada. Para garantir uma ordem de inicialização consistente, é necessário usar especializações explícitas.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3