Como evitar a inicialização em dois passos (C ++)?

5

Eu gostaria de seguir o idioma RAII (aquisição de recursos é inicialização) em todo o meu código, mas também estou fazendo o modelo padrão onde estou desenvolvendo versões genéricas de minhas classes e usando-as para construir uma base de código comum. coisas. Às vezes eu preciso impor uma sequência de inicialização onde eu precisaria chamar as funções virtuais do objeto especializado no construtor, mas isso não é possível em C ++. A única solução que consigo pensar é uma inicialização em dois passos chamando uma função init depois que o objeto é criado, mas isso quebra o idioma RAII. Existe alguma solução para isso?

#include <memory>

class A {
public:
    A() {
        // I want to call B's foo() here
    }
    virtual void foo() = 0;
};

class B : public A {
public:
    B() {};
    virtual void foo() {};
};

void main() {
    std::unique_ptr<A> a(static_cast<A*>(new B));

    // Use b polymorphically from here...
}
    
por navark 07.01.2017 / 01:34
fonte

2 respostas

5

Você pode usar a abordagem de tornar o construtor de A protegido, o construtor de B privado e, em seguida, criar um auxiliar estático de classe para instanciar B; o ajudante estático faria então a inicialização de dois estágios; Isso garantiria que a instanciação seja sempre feita corretamente e tornar o construtor privado / protegido garante que você não tente instanciar a classe acidentalmente diretamente. Isso tem a desvantagem de não ser possível instanciar a classe na pilha ou como um membro - ela precisa estar na pilha.

    
por 07.01.2017 / 03:55
fonte
0

Você não pode chamar as funções de B do construtor A , porque o B subobject ainda não existe .
Qualquer design que dependesse de uma chamada de função virtual de um construtor pai é sem sentido.

A solução é simplesmente chamar foo() do construtor B .

    
por 11.01.2017 / 15:06
fonte