是否std::make_unique有像任何效率优势std::make_shared?
与手动构建相比std::unique_ptr:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
Run Code Online (Sandbox Code Playgroud) 据我所知,引入了C++ 14 std::make_unique,因为由于没有指定参数评估顺序,这是不安全的:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
Run Code Online (Sandbox Code Playgroud)
(说明:如果评估首先为原始指针分配内存,则g()在std::unique_ptr构造之前抛出调用和异常,然后内存泄漏.)
呼叫std::make_unique是一种约束呼叫顺序的方法,从而使事情变得安全:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Run Code Online (Sandbox Code Playgroud)
从那以后,C++ 17澄清了评估顺序,使得Syntax A也安全,所以这里是我的问题:在C++ 17中仍然有理由使用std::make_uniqueover std::unique_ptr的构造函数吗?你能举一些例子吗?
截至目前,我能想象的唯一原因是它只允许输入MyClass一次(假设您不需要依赖多态std::unique_ptr<Base>(new Derived(param))).但是,这似乎是一个非常弱的原因,特别是当构造函数std::make_unique不允许指定删除器时std::unique_ptr.
而且为了清楚起见,我并不是主张std::make_unique从标准库中删除(至少为了向后兼容而保持它有意义),而是想知道是否仍然存在强烈倾向于它的情况std::unique_ptr
std::vector在 std::containers (或std::array)和指向数组的智能指针之间进行选择时如何决定
我知道容器是内存管理的对象。它们是异常安全的,不会有任何内存泄漏,它们还提供了内存管理的功能(push.back等),而智能指针也是不会泄漏内存的指针,因为它们在不再需要时会删除它们(就像超出范围时的 unique_ptr 一样)。在容器中,每次创建它们时可能都会产生开销。
我的问题是我如何决定使用哪种方法以及为什么。
std::vector <unsigned char>myArray(3 * outputImageHight * outputImageWidth);
std::unique_ptr<unsigned char[]>myArray(new unsigned char[3 * outputImageHight * outputImageWidth]);
Run Code Online (Sandbox Code Playgroud) 我目前正在学习C++,来自C#/ Java背景,使用visual studio 2017.
我有一个关于在堆上创建对象并在路上正确引用它们的问题.到目前为止,我遇到了多个教程和做事方式.有些人建议尽可能使用智能指针,其他人则发誓使用魔鬼工具.
我目前的主要看起来像这样:
//Main
Person *makePerson()
{
string name;
int age;
cout << "Input name: ";
cin >> name;
cout << "Input age: ";
cin >> age;
return new Person(name, age);
}
Child *makeChild(Person &parent)
{
return new Child(*makePerson(), &parent);;
}
int main()
{
cout << "---Input parent data---" << endl;
Person *person = makePerson();
cout << "printing: " << *person << endl;
cout << "---Input child data---" << endl;
Child *child = makeChild(*person);
cout …Run Code Online (Sandbox Code Playgroud) 一个简单的代码
class Base {};
class Derived : Base {};
unique_ptr<Base> Create() {
unique_ptr<Base> basePtr = make_unique<Derived>(); // compile error
return basePtr;
}
Run Code Online (Sandbox Code Playgroud)
产生编译错误("没有合适的转换").我找到了类似的问题,解决方案的用途std::move.我试过这个
unique_ptr<Derived> derived = make_unique<Derived>();
unique_ptr<Base> basePtr = std::move(derived); // compile error
Run Code Online (Sandbox Code Playgroud)
但现在std::move产生编译错误.我还发现问题在哪里(如果我理解的话),如果我们使用,演员应该是自动的
unique_ptr<Base> basePtr = make_unique<Derived>(new Derived()); //compile error
Run Code Online (Sandbox Code Playgroud)
但这也不起作用(编译错误),也不建议使用new智能指针.
什么是正确的解决方案?
到目前为止我找到的唯一可行解决方案
unique_ptr<Base> basePtr = unique_ptr<Base>((Base*)new Derived());
Run Code Online (Sandbox Code Playgroud)
看起来真的很难看.
在我的项目中,我需要包含指向数据单元实例的智能指针的容器。我写的类(简单的例子):
template <typename T>
class Queue
{
public:
void push(const T & param)
{
m_deque.push_front(param);
}
private:
std::deque<T> m_deque;
};
Run Code Online (Sandbox Code Playgroud)
比我想推一个:
int main()
{
Queue< std::unique_ptr<DataBox> > queue;
std::unique_ptr<DataBox> d1(new DataBox(11));
queue.push(d1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而 VS2017 编译器说我不能这样做:
Error C2280 std::unique_ptr<DataBox,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
据我了解,错误的原因是尝试制作 unique_ptr 的副本。但是,如果我将签名更改为:
void push(T && param) {...}
和函数调用
queue.push( std::move(d1) );
我又犯了这个错误。所以问题是 - 我应该如何实现push()将移动unique_ptr到队列?
是否有透明的std::unique_ptr容器使用方式?
#include <iostream>
#include <memory>
#include <map>
struct method {
virtual ~method() { std::cout << "f\n"; };
};
typedef std::unique_ptr<method> MPTR;
std::map<int, MPTR> tbl;
void insert(int id, method *m) {
tbl.insert({id,std::unique_ptr<method>(m)});
};
void set(int id, method *m) {
tbl[id] = std::unique_ptr<method>(m);
};
int main(int argc, char **argv) {
insert(1,new method());
set(1,new method());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想使用tbl.insert({id,m});和tbl[id] = m;等,而不必为每次访问包装/解包.
std::map.c++ ×7
unique-ptr ×5
c++17 ×2
pointers ×2
c++11 ×1
c++14 ×1
containers ×1
heap ×1
raw-pointer ×1
shared-ptr ×1
stdmap ×1