Dlaczego std :: shared_ptr nie musi znać kompletnego typu, jeśli jest skonstruowany z wartości innej niż null?

Mam fabryczną funkcję w factory.h, która zwraca std :: shared_ptr do klasy bazowej w foo.h. Factory.h używa deklaracji forward do klasy bazowej zamiast dołączać foo.h. Jak następujący kod:

factory.h:

#include <memory>

// forward declaration
class foo;

std::shared_ptr<foo> create_foo_A(int A);
std::shared_ptr<foo> create_foo_B(int A, int B);
void work_with_foo(std::shared_ptr<foo> ptr);

W kodzie klienta, jeśli std :: shared_ptr na foo zostało zainicjowane za pomocą nullptr, kompilator ostrzeże.

main.cpp:

#include "factory.h"
int main()
{
    int type = 1;

    std::shared_ptr<foo> ptr(nullptr);    // <--- compile warning
    if (type == 1)
        ptr = create_foo_A(5566);
    else
        ptr = create_foo_B(5566, 7788);
    work_with_foo(ptr);

    return 0;
}

Komunikat ostrzegawczy brzmi:

warning C4150 : deletion of pointer to incomplete type 'foo'; no destructor called

Jest to rozsądne, ponieważ std :: shared_ptr nie zna kompletnego typu foo. To ostrzeżenie można usunąć, jeśli main.cpp zawiera foo.h.

Ale jeśli std :: shared_ptr został zainicjowany z non-nullptr, kompilacja nie ostrzegłaby. main.cpp:

#include "factory.h"
int main()
{
    int type = 1;

    if (type == 1)
    {
        std::shared_ptr<foo> ptr = create_foo_A(5566);    // <--- OK
        work_with_foo(ptr);
    }
    else
    {
        std::shared_ptr<foo> ptr = create_foo_B(5566, 7788);    // <--- OK
        work_with_foo(ptr);
    }

    return 0;
}

W tej scenie dlaczego std :: shared_ptr nie musi znać kompletnego typu klasy foo? Czy jest zupełnie inaczej, gdy std :: shared_ptr jest skonstruowany z nullptr i nie-null?

questionAnswers(3)

yourAnswerToTheQuestion