使用 new 运算符定义 std::shared_ptr 时出错
error when defining a std::shared_ptr with new operator
我正在尝试通过以下方式使用 new
运算符定义 std::shared_ptr
:
#include <memory>
struct A {
};
int main() {
std::shared_ptr<A> ptr = new A();
return 0;
}
但是我得到了以下编译时错误:
main.cpp: In function 'int main()':
main.cpp:8:30: error: conversion from 'A*' to non-scalar type 'std::shared_ptr' requested std::shared_ptr ptr = new A();
无论如何,以下绝对有效:
std::shared_ptr<A> ptr{new A()};
有谁知道为什么会这样吗?
tl;dr: 这是相关构造函数 explicit
.
的结果
当您使用 =
初始化时,您调用了复制初始化。 C++ 不允许从原始指针对 shared_ptr
进行复制初始化,因为很容易导致从某个任意原始指针到实际上并不存在的 shared_ptr
的意外隐式转换管理它。
这样,您可以 "ensnare" 将原始指针 shared_ptr
的唯一方法是非常有意且非常明确的(正如您在第二个示例中正确完成的那样)。现在,只有在这个初始化程序中,您才需要记住不要使用您已经在别处管理的指针这样做。
特定线路 std::shared_ptr<A> ptr = new A()
是否存在任何实际危险?不,但您所看到的是各种 C++ 规则协同工作的结果。
你可以把你的语句想象成这样的 2 行。
A* a = new A();
std::shared_ptr<A> ptr = a;
虽然在这种情况下这在更复杂的代码中可能是正确的,但它可能会导致潜在的陷阱,因此不允许对原始指针进行复制初始化。
想象一下
A* a = new A();
//.....
std::shared_ptr<A> ptr = a;
//.....
std::shared_ptr<A> ptr2 = a; //second ptr holding a... UB
在这里你会有 2 个共享指针持有同一个对象,这会导致麻烦。
为了避免那些 "implicit" 错误,C++ 不允许这种初始化。
虽然您仍然可以使用构造函数,但它更 "verbose" 并且更难意外分配指针。
std::shared_ptr<A> ptr{ new A() };
这看起来更像是构造一个新对象,可能不会意外导致错误分配。
此外,首选 在现代中创建共享指针的方法是
auto ptr = std::make_shared<A>();
我正在尝试通过以下方式使用 new
运算符定义 std::shared_ptr
:
#include <memory>
struct A {
};
int main() {
std::shared_ptr<A> ptr = new A();
return 0;
}
但是我得到了以下编译时错误:
main.cpp: In function 'int main()':
main.cpp:8:30: error: conversion from 'A*' to non-scalar type 'std::shared_ptr' requested std::shared_ptr ptr = new A();
无论如何,以下绝对有效:
std::shared_ptr<A> ptr{new A()};
有谁知道为什么会这样吗?
tl;dr: 这是相关构造函数 explicit
.
当您使用 =
初始化时,您调用了复制初始化。 C++ 不允许从原始指针对 shared_ptr
进行复制初始化,因为很容易导致从某个任意原始指针到实际上并不存在的 shared_ptr
的意外隐式转换管理它。
这样,您可以 "ensnare" 将原始指针 shared_ptr
的唯一方法是非常有意且非常明确的(正如您在第二个示例中正确完成的那样)。现在,只有在这个初始化程序中,您才需要记住不要使用您已经在别处管理的指针这样做。
特定线路 std::shared_ptr<A> ptr = new A()
是否存在任何实际危险?不,但您所看到的是各种 C++ 规则协同工作的结果。
你可以把你的语句想象成这样的 2 行。
A* a = new A();
std::shared_ptr<A> ptr = a;
虽然在这种情况下这在更复杂的代码中可能是正确的,但它可能会导致潜在的陷阱,因此不允许对原始指针进行复制初始化。
想象一下
A* a = new A();
//.....
std::shared_ptr<A> ptr = a;
//.....
std::shared_ptr<A> ptr2 = a; //second ptr holding a... UB
在这里你会有 2 个共享指针持有同一个对象,这会导致麻烦。
为了避免那些 "implicit" 错误,C++ 不允许这种初始化。
虽然您仍然可以使用构造函数,但它更 "verbose" 并且更难意外分配指针。
std::shared_ptr<A> ptr{ new A() };
这看起来更像是构造一个新对象,可能不会意外导致错误分配。
此外,首选 在现代中创建共享指针的方法是
auto ptr = std::make_shared<A>();