c++11新特性
智能指针
shared_ptr
- 共享所有权:多个
shared_ptr
可以共同拥有同一个对象。当最后一个shared_ptr
被销毁时,管理的对象会被自动删除,避免内存泄漏。 - 引用计数:
shared_ptr
会维护一个引用计数,记录有多少个shared_ptr
指向同一对象。当创建一个新的shared_ptr
指向同一对象时,引用计数增加;当一个shared_ptr
被销毁或指向其他对象时,引用计数减少。 - 自动内存管理:
shared_ptr
在其作用域结束时会自动释放内存。
核心接口:
创建p1
shared_ptr<int> p1= make_shared<int>(18);
拷贝构造:
shared_ptr<int> p2= p1;
p1和p2共同拥有一个对象,此时use_count = 2;
当其中一个超出作用域后,use_count减1,当use_count = 0时,销毁对象
reset(),将其指向 nullptr
或者其他对象。可以选择性地传入新对象。
void reset();
void reset(T* ptr);
void reset(T* ptr, deleter_type d);
weak_ptr
weak_ptr
也是 C++11 引入的智能指针,主要用于解决循环引用的问题。它并不增加对象的引用计数,而是对对象的“弱引用”,即它不会影响对象的生命周期。
特点:
- 不影响引用计数:
weak_ptr
不会增加shared_ptr
的引用计数,因此它不会阻止对象的销毁。 - 避免循环引用:当两个对象互相持有
shared_ptr
时,如果没有weak_ptr
,就会发生循环引用,导致内存泄漏。weak_ptr
可以用来打破这种循环引用。 - 可以转换为
shared_ptr
:weak_ptr
可以通过lock()
方法转换为shared_ptr
。如果对象已经被销毁,lock()
返回一个空的shared_ptr
。
核心接口:
shared_ptr<int> p1 = make_shared<int>(10);
weak_ptr<int> p2 = p1
此时p1的use_count仍为1,如果
auto ptr2 = p2.lock()
此时ptr2为一个shared_ptr,p2如果为空,则返回一个空的 shared_ptr
检查是否释放
bool expired() const;
weak_ptr
的 reset()
方法用于重置 weak_ptr
的状态,使其不再指向任何对象。
weak_ptr 的 reset() 方法用于重置 weak_ptr 的状态,使其不再指向任何对象。
unique_ptr
独占所有权,没有赋值函数和拷贝函数
核心接口:
release()返回指向的对象的指针,但不会删除对象,并释放所有权
unique<int> p1(new int(18));
int *p2 = p1.release();
delete p2;
reset()替换被管理的对象
unique<int> p1 = make_shared<int>(10);
p1.reset(); // 释放 ptr 管理的对象,并将 ptr 设为 nullptr
p1.reset(new int(20)); // 释放当前对象,并将 ptr 重新指向新创建的对象
swap()交换被管理的对象
std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
std::unique_ptr<int> ptr2 = std::make_unique<int>(20);
// 交换两个 unique_ptr 的所有权
ptr1.swap(ptr2);
算法
leetcode-20 有效括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
思路分析:使用栈stack,每遇到一个左括号就把括号压入栈,遇到右括号时,查看栈顶,如果有匹配的,则弹出栈,最后检查是否栈空,栈空则为true
代码:
class Solution {
public:
bool isValid(string s) {
stack<char> sta;
unordered_map<char,char> record= {
{')','('},
{']','['},
{'}','{'}
};
for(auto& c:s)
{
if(record.find(c)!=record.end())
{
if(!sta.empty()&&sta.top() == record[c])
{
sta.pop();
}
else{
return false;
}
}
else
{
sta.push(c);
}
}
return sta.empty();
}
};
初始化:定义一个栈,和哈希表,键值为右括号,用于搜索。
stack<char> sta;
unordered_map<char,char> record= {
{')','('},
{']','['},
{'}','{'}
};
遍历字符串,发现是右括号,则判断栈顶元素是否为对应的左括号,是的话弹出栈顶元素,否则返回false
for(auto& c:s)
{
if(record.find(c)!=record.end())
{
if(!sta.empty()&&sta.top() == record[c])
{
sta.pop();
}
else{
return false;
}
}
else
{
sta.push(c);
}
}
leetcode-155 最小栈
问题描述:
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
思路分析,主要看如何找最小栈,我们可以设计一个min_stack,在每次压入新的元素时候,存入最小值在栈顶,最后只需要取出min_stack的top即可
代码实现:
class MinStack {
public:
stack<int> min_stack;
stack<int> stack;
MinStack() {
min_stack.push(INT_MAX);
}
void push(int val) {
stack.push(val);
min_stack.push(min(min_stack.top(), val));
}
void pop() {
stack.pop();
min_stack.pop();
}
int top() {
return stack.top();
}
int getMin() {
return min_stack.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
我觉得没啥好说的,挺简单的