gpt4 book ai didi

c++ - 如果 std::shared_ptr 是从非空构造的,为什么它不需要知道完整类型?

转载 作者:搜寻专家 更新时间:2023-10-30 23:58:18 25 4
gpt4 key购买 nike

我在 factory.h 中有一个工厂函数,它返回一个 std::shared_ptrfoo.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编译器会发出警告。

ma​​in.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 的完整类型。如果 ma​​in.cpp 包含 foo.h,则可以删除此警告。

但是如果std::shared_ptr使用非 nullptr 初始化,编译器不会发出警告。

ma​​in.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需要知道类的完整类型foostd::shared_ptr时有很大不同吗?由 nullptr 构成和非 nullptr

最佳答案

这个:

std::shared_ptr<foo> ptr(nullptr);

不应该警告。这是一个完全有效的陈述,不需要知道 foo 的完整类型.很可能是因为 nullptr 向您发出警告正在被效仿。这也不应该警告:

std::shared_ptr<foo> ptr;

并且两者被指定为等价的:

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?

create_foo_A定义create_foo_B需要知道 foo 的完整类型.但声明没有。

简而言之,shared_ptr<T>::shared_ptr(U*)构造函数需要知道 U 的完整定义.但几乎没有别的。这个答案中有一个更完整的调查:

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

所以如果你改为:

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

然后你有未定义的行为。显然 VC++ 会发出警告。 libc++ 给出了一个硬错误。而使用 nullptr非常好,至少根据 C++11。

总而言之,您的示例都不需要 foo 的完整定义.


[util.smartptr.shared.dest]

~shared_ptr();

效果:

  • 如果*this 或与另一个人共享所有权 shared_ptr实例 ( use_count() > 1 ),没有副作用。

[util.smartptr.shared.const]

constexpr shared_ptr() noexcept;

效果:构造一个 shared_ptr对象。


[util.smartptr.shared]

在大纲中:

constexpr shared_ptr(nullptr_t) : shared_ptr() { }

关于c++ - 如果 std::shared_ptr 是从非空构造的,为什么它不需要知道完整类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20985667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com