Why doesn't std::shared_ptr need to know complete type if it's constructed from non-null?

后端 未结 3 450
失恋的感觉
失恋的感觉 2021-01-22 04:47

I have a factory function in factory.h which returns an std::shared_ptr to a base class in foo.h. factory.h uses

3条回答
  •  没有蜡笔的小新
    2021-01-22 05:36

    This:

    std::shared_ptr ptr(nullptr);
    

    should not warn. It is a perfectly valid statement, and has no need to know the complete type of foo. It is likely that it is warning for you because nullptr is being emulated. Neither should this warn:

    std::shared_ptr ptr;
    

    and the two are specified to be equivalent:

    constexpr shared_ptr(nullptr_t) : shared_ptr() { }
    

    In this scene, why doesn't std::shared_ptr need to know the complete type of class foo?

    The definitions of create_foo_A and create_foo_B will need to know the complete type of foo. But the declarations do not.

    In a nutshell, the shared_ptr::shared_ptr(U*) constructor needs to know the complete definition of U. But little else does. There is a more complete survey in this answer:

    https://stackoverflow.com/a/6089065/576911

    So if you said instead:

    std::shared_ptr ptr((foo*)0);
    

    Then you have undefined behavior. Apparently VC++ will warn. libc++ gives a hard error. Whereas using nullptr is quite ok, at least according to C++11.

    In summary, none of your examples require the complete definition of foo.


    [util.smartptr.shared.dest]

    ~shared_ptr();

    Effects:

    • If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1), there are no side effects.

    [util.smartptr.shared.const]

    constexpr shared_ptr() noexcept;

    Effects: Constructs an empty shared_ptr object.


    [util.smartptr.shared]

    In the synopsis:

    constexpr shared_ptr(nullptr_t) : shared_ptr() { }
    

提交回复
热议问题