C艹智能指针
指针类型
std::unique_ptr<类名> 指针名
得到智能指针(但是这个只是一个普通指针的用法)
class W{
public:
int age=10;
};
int main (){
std::unique_ptr<W> emm(new W());//只能显式调用
std::cout<<emm->age<<std::endl;
}
make_unique
完美传递了参数给对象的构造函数
异常安全:std::make_unique
在对象构造过程中如果抛出异常,不会导致内存泄漏,而 new
可能会导致内存泄漏。
单次内存分配:std::make_unique
通常会进行单次内存分配,性能更优。
代码简洁:std::make_unique
使代码更简洁,减少了手动管理内存的复杂性。
从一个原始指针构造出一个std::unique_ptr
,返回创建的std::unique_ptr
,同时开始具有自动删除对象的功能
class W{
public:
int age=10;
};
int main (){
std::unique_ptr<W> emm=std::make_unique<W>();
std::cout<<emm->age<<std::endl;
}
但是要注意,这个指针无法复制,因为在离开作用域或这个指针被删除时,对象会一起删除
所以要用上共享指针(主要是通过记录引用次数来确定是否有引用)
当所有引用都寄了,对象才会寄
class W{
public:
int age=10;
};
int main (){
std::shared_ptr<W> emm=std::make_shared<W>();
std::shared_ptr eq=emm;//同一个对象
std::cout<<emm->age<<std::endl;
std::cout<<eq->age<<std::endl;
}
同时,有绕过计数的指针
std::weak_ptr we = emm;
//std::weak_ptr是不会增加引用计数的,
// 它指向的对象如果因为shared_ptr的引用计数变为0而被删除了,那么weak_ptr也会自动变成空指针.
构造类型
new
的作用
new
关键字用于在堆上分配内存并构造对象。例如,new Vector2()
分配内存并构造一个Vector2
对象。new
返回一个指向分配内存的原始指针。- 使用
new
分配的内存需要手动管理(如通过delete
释放),否则会导致内存泄漏。
std::make_shared
的作用
std::make_shared<T>(args...)
用于在堆上分配内存、构造对象并返回一个std::shared_ptr<T>
。- 它不仅分配和构造对象,还会分配一个控制块(control block),该控制块管理引用计数和弱引用计数。
std::shared_ptr
自动管理内存,引用计数降为零时,内存会自动释放,避免了内存泄漏的问题。std::make_shared
在一次内存分配中同时分配对象和控制块,提高了内存分配的效率,并且在异常情况下更安全。
std::make_unique
的作用
std::make_unique<T>(args...)
用于在堆上分配内存、构造对象并返回一个std::unique_ptr<T>
。std::unique_ptr
是一种独占所有权的智能指针,即同一时间只能有一个std::unique_ptr
拥有该对象的所有权,不能共享所有权。- 与
std::shared_ptr
不同,std::unique_ptr
不管理引用计数,因此更轻量,更适用于不需要共享所有权的场景。
对比
内存管理:
new
:需要手动管理内存,可能导致内存泄漏。std::make_shared
:智能指针自动管理内存,引用计数为零时自动释放内存。
内存分配效率:
new
:对象和控制块(如果使用智能指针)可能需要两次内存分配。std::make_shared
:对象和控制块在一次内存分配中完成,提高了效率。
异常安全性:
new
:在内存分配和智能指针构造之间可能引发异常,导致内存泄漏。std::make_shared
:在内存分配和对象构造时更安全,避免了内存泄漏风险。
所有权:
std::unique_ptr
:独占所有权,不允许多个指针共享同一个对象。std::shared_ptr
:共享所有权,多个指针可以共享同一个对象,通过引用计数管理对象的生命周期。
内存管理:
std::unique_ptr
:独占所有权的智能指针,自动释放内存。std::shared_ptr
:共享所有权的智能指针,通过引用计数管理内存,最后一个指针销毁时释放内存。
内存分配效率:
std::make_unique
和std::make_shared
都会在一次内存分配中完成对象和控制块的分配(对于std::shared_ptr
)。std::unique_ptr
更轻量,因为它不需要管理引用计数。
Comments NOTHING