看一下之前的堆栈问题 std:make_shared vs std :: shared_ptr,我试图在uni项目中实现它.这是之前的"问题":
我想不出任何情况
std::shared_ptr<Object> obj(new Object("foo", 1));会优先考虑
auto obj = std::make_shared<Object>("foo", 1);
因此我采用了这段代码:
std::shared_ptr<Triangle> pT1(new Triangle(pCanvas, 30, 30, 30, 60, 60, 30, 255, 0, 0));
Run Code Online (Sandbox Code Playgroud)
并将其修改为此代码:
auto pT1 = std::make_shared<Triangle>(pCanvas, 30, 30, 30, 60, 60, 30, 255, 0, 0);
Run Code Online (Sandbox Code Playgroud)
但是,std :: make_shared以红色下划线,当我鼠标悬停时,我得到错误:"错误:没有重载函数的实例"std :: make_shared"匹配参数列表"
我的代码使用第一行代码正确编译和执行,但如果我使用第二行,则会出现一些错误.
这些错误是:
`1> ------ Build build:Project:SIT153Canvas,配置:Debug Win32 ------ 1> main.cpp
1> c:\ users\steve\documents\visual studio 2012\projects\sit153canvas\main.cpp(54):错误C2780:'std :: shared_ptr <_Ty> std :: make_shared(_V0_t &&,_ V1_t &&,_ V2_t && ,_V3_t &&,_ V4_t &&)':预计有5个参数 …
这个链接的问题询问make_shared<>函数和shared_ptr<>构造函数是否不同.
部分答案是,make_shared<>通常会在单个分配中为指向对象和智能指针控制块分配内存.该shared_ptr<>构造函数使用两个分配.
cppreference指出构造函数"必须"这样做,但没有给出任何理由.
为什么是这样?是出于某种原因不可能吗?或者由于其他原因,标准是否禁止它?
我试图了解如何std::shared_ptr在C++中使用.但它很混乱,我不明白如何创建指向同一对象的多个共享指针.即使是文档和在线资料也不是很清晰.
以下是我编写的一小段代码,用于尝试和理解其std::shared_ptr行为:
#include <iostream>
#include <memory>
using namespace std;
class Node
{
public:
int key;
Node()
{
key = 0;
}
Node(int k)
{
key = k;
}
};
int main()
{
Node node = Node(10);
shared_ptr<Node> ptr1((shared_ptr<Node>)&node);
cout << "Use Count: " << ptr1.use_count() << endl;
// shared_ptr<Node> ptr2=make_shared<Node>(node);//This doesn't increase use_count
shared_ptr<Node> ptr2((shared_ptr<Node>)&node);
cout << "Use Count: " << ptr2.use_count() << endl;
if (ptr1 == ptr2)
cout << "ptr1 & ptr2 point to the …Run Code Online (Sandbox Code Playgroud) 使用std::make_shared<C>该类时,不会调用重载的new / delete运算符。
使用时std::shared_ptr<C>,std::unique_ptr<C>与std::make_unique<C>类超载新/使用delete运算符。
查看文档时,它是完全正确的且有据可查。
cppreference解释了该行为:
std::make_shared使用:: new,因此,如果使用特定于类的运算符new设置了任何特殊行为,则它将不同于std::shared_ptr<T>(new T(args...))。
下面是一些伪代码,可以更好地突出显示行为:
#include <memory>
class C {
public:
void* operator new(size_t size) {
void* p = ::operator new(size);
std::cout << "C::new() -> " << p << "\n";
return p;
}
void operator delete(void* p) {
std::cout << "C::delete() -> " << p << "\n";
::operator delete(p);
}
};
std::shared_ptr<C> ptr = std::make_shared<C>();
Run Code Online (Sandbox Code Playgroud)
从外部的角度来看,它似乎不一致且容易出错。应该始终使用重载类new / delete运算符。
那么,这种行为的原理是什么?
而且,C ++规范在哪里详细说明了std::make_shared行为? …
我正在尝试通过在std :: make_shared上调用std :: bind来创建一个返回shared_ptr的仿函数,但是语法超出了我,或者甚至可能不可能?假设MyBar的构造函数对MyFoo采用const引用,则类似于以下内容:
std::function<std::shared_ptr<MyBar>(const MyFoo &)> functor = std::bind(&std::make_shared<MyBar>, std::placeholders::_1);
Run Code Online (Sandbox Code Playgroud) 我如何调用make_shared或make_unique具有模板化构造函数的类?这是一个例子:
class A
{
/// constructor shared ptr
A(shared_ptr<X> x) ...
/// constructor that creates new shared ptr
template <class T> A() : A(make_shared<T>(...)) {}
};
Run Code Online (Sandbox Code Playgroud)
make_shared<A<T>>() 没有意义(也没有编译),因为那宁可是模板化的类,而不是模板化的构造函数.
既没有make_shared<A><T>()也没有make_shared<A>(<T>())编译 - 也看起来不应该.同上make_shared<A, T>()
有没有办法在调用中为构造函数调用指定模板make_shared?我认为答案适用于make_unique; 如果没有,请说明.谢谢!
(为了澄清模板是如何工作的,我编辑了代码.)
有什么区别
auto sp = std::make_shared<Foo>();
auto sp(std::make_shared<Foo>());
Run Code Online (Sandbox Code Playgroud)
需要详细说明.
正如在C++中对make_shared中的差异和普通的shared_ptr的回答所指出的那样,在大多数情况下都make_shared表现优异shared_ptr.
那么为什么C++标准既定义了两者shared_ptr又make_shared一起定义了?是否有任何我更喜欢的情况shared_ptr,make_shared甚至我只能使用shared_ptr但不能使用的情况make_shared?
这段代码编译干净,适用于我尝试过的所有编译器,除了GCC 8(和当前的GCC主干):
std::make_shared<volatile int>(0)
Run Code Online (Sandbox Code Playgroud)
我想知道:
std::atomic,但语义不一样所以建议使用它而volatile不是我正在寻找的.请在此处查看:https://godbolt.org/z/rKy3od
我最近正在处理 shared_ptr 的问题。我很好奇如果 make_shared 失败,它会引发异常吗?是否有任何一种情况 make_shared 返回 nullptr 但没有任何例外?