Почему std :: shared_ptr не должен знать полный тип, если он создан из ненулевого значения?

У меня есть фабричная функция в factory.h, которая возвращает std :: shared_ptr в базовый класс в foo.h. Factory.h использует прямое объявление для базового класса вместо включения foo.h. Как следующий код:

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);

В клиентском коде, если std :: shared_ptr для foo инициализируется с помощью nullptr, компилятор предупредит об этом.

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;
}

Предупреждающее сообщение:

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

Это разумно, так как std :: shared_ptr не знает полный тип foo. Это предупреждение может быть удалено, если main.cpp включает foo.h.

Но если std :: shared_ptr был инициализирован не-nullptr, компиляция не будет предупреждать. 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;
}

В этой сцене, почему std :: shared_ptr не нужно знать полный тип класса foo? Разве это сильно отличается, когда std :: shared_ptr создается с nullptr и ненулевым?

Ответы на вопрос(3)

Ваш ответ на вопрос