动态内存管理
本文最后更新于:2022年3月19日 凌晨
此文取自于👉动态内存管理 - cppreference.com
std::unique_ptr#
拥有独有对象所有权语义的智能指针
#include <iostream>
#include <vector>
#include <memory>
#include <cstdio>
#include <fstream>
#include <cassert>
#include <functional>
struct B {
virtual void bar() { std::cout << "B::bar\n"; }
virtual ~B() = default;
};
struct D : B
{
D() { std::cout << "D::D\n"; }
~D() { std::cout << "D::~D\n"; }
void bar() override { std::cout << "D::bar\n"; }
};
// 消费 unique_ptr 的函数能以值或以右值引用接收它
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
p->bar();
return p;
}
void close_file(std::FILE* fp) { std::fclose(fp); }
int main()
{
std::cout << "unique ownership semantics demo\n";
{
auto p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
auto q = pass_through(std::move(p));
assert(!p); // 现在 p 不占有任何内容并保有空指针
q->bar(); // 而 q 占有 D 对象
} // ~D 调用于此
std::cout << "Runtime polymorphism demo\n";
{
std::unique_ptr<B> p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
// 作为指向基类的指针
p->bar(); // 虚派发
std::vector<std::unique_ptr<B>> v; // unique_ptr 能存储于容器
v.push_back(std::make_unique<D>());
v.push_back(std::move(p));
v.emplace_back(new D);
for(auto& p: v) p->bar(); // 虚派发
} // ~D called 3 times
std::cout << "Custom deleter demo\n";
std::ofstream("demo.txt") << 'x'; // 准备要读的文件
{
std::unique_ptr<std::FILE, void (*)(std::FILE*) > fp(std::fopen("demo.txt", "r"),
close_file);
if(fp) // fopen 可以打开失败;该情况下 fp 保有空指针
std::cout << (char)std::fgetc(fp.get()) << '\n';
} // fclose() 调用于此,但仅若 FILE* 不是空指针
// (即 fopen 成功)
std::cout << "Custom lambda-expression deleter demo\n";
{
std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr)
{
std::cout << "destroying from a custom deleter...\n";
delete ptr;
}); // p 占有 D
p->bar();
} // 调用上述 lambda 并销毁 D
std::cout << "Array form of unique_ptr demo\n";
{
std::unique_ptr<D[]> p{new D[3]};
} // 调用 ~D 3 次
}
#
拥有共享对象所有权语义的智能指针
#include <iostream>
#include <memory>
class Sample
{
public:
Sample() { std::cout << "This is Sample." << std::endl; }
void smartpointer()
{
std::cout << "This is smartpointer." << std::endl;
}
~Sample() { std::cout << "Destory Sample." << std::endl; }
};
int main()
{
auto pointer = std::make_shared<Sample>();
// pointer->smartpointer();
// std::shared_ptr<Sample> sample1(new Sample());
std::shared_ptr<Sample> sample1 = pointer;
sample1->smartpointer();
std::shared_ptr<Sample> sample12(std::make_shared<Sample>());
sample12->smartpointer();
return 0;
}
std::weak_ptr#
到
std::shared_ptr
所管理对象的弱引用
std::weak_ptr
类型指针不会导致堆内存空间的引用计数增加或减少
std::shared_ptr
依然存在着资源无法释放的问题,比如class A中有class B成员变量,class B中有class A成员变量,这种情况就存在引用计数不为0的问题。
#include <iostream>
#include <memory>
struct A;
struct B;
struct A
{
//std::shared_ptr<B> pointer;
std::weak_ptr<B> ptr;
std::shared_ptr<B> ptr_ = ptr.lock();
~A()
{
std::cout << "A 被销毁" << std::endl;
}
};
struct B
{
//std::shared_ptr<A> pointer;
std::weak_ptr<A> ptr;
std::shared_ptr<A> ptr_ = ptr.lock();
~B()
{
std::cout << "B 被销毁" << std::endl;
}
};
int main()
{
auto a = std::make_shared<A>();
//std::weak_ptr<A> ptr_a(a);
auto b = std::make_shared<B>();
//std::weak_ptr<B> ptr_b(b);
a->ptr = b;
//a->pointer = b;
b->ptr = a;
//b->pointer = a;
}
结果:
End.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!