Appearance
c++中智能指针的应用
涉及到的头文件包括<memory>
独占指针 std::unique_ptr
独占指针是一种带有所有权的智能指针
在私有成员中使用:
cpp
#include <memory>
struct Info {};
class Test {
public:
Test() : info_(std::make_unique<Info>()) {}
~Test() = default;
private:
std::unique_ptr<Info> info_ = nullptr;
};
#include <memory>
struct Info {};
class Test {
public:
Test() : info_(std::make_unique<Info>()) {}
~Test() = default;
private:
std::unique_ptr<Info> info_ = nullptr;
};
在传递消息时使用:
cpp
#include <memory>
struct Info {
// 超~大的结构体
};
class Container {
public:
void Set(std::unique_ptr<Info> info) {
// do something.
}
};
class Test {
public:
Test() : container_(std::make_unique<Container>()) {}
void Make() {
std::unique_ptr<Info> info = std::make_unique<Info>();
container_->Set(std::move(info));
}
private:
std::unique_ptr<Container> container_;
};
#include <memory>
struct Info {
// 超~大的结构体
};
class Container {
public:
void Set(std::unique_ptr<Info> info) {
// do something.
}
};
class Test {
public:
Test() : container_(std::make_unique<Container>()) {}
void Make() {
std::unique_ptr<Info> info = std::make_unique<Info>();
container_->Set(std::move(info));
}
private:
std::unique_ptr<Container> container_;
};
使用独占指针存储数组
cpp
#include <cstdlib>
#include <cstring>
#include <memory>
void *originData = std::malloc(1024);
std::unique_ptr<uint8_t[]> Make() {
std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(1024);
memcpy(data.get(), originData, 1024);
return data;
}
class ImageContainer {
public:
void MakeImage() {
data_ = Make();
}
private:
std::unique_ptr<uint8_t[]> data_ = nullptr;
};
#include <cstdlib>
#include <cstring>
#include <memory>
void *originData = std::malloc(1024);
std::unique_ptr<uint8_t[]> Make() {
std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(1024);
memcpy(data.get(), originData, 1024);
return data;
}
class ImageContainer {
public:
void MakeImage() {
data_ = Make();
}
private:
std::unique_ptr<uint8_t[]> data_ = nullptr;
};
巧用deleter
cpp
#include <fstream>
#include <memory>
void Write(const char *fileData, size_t size, const char* fileName) {
auto deleter = [] (std::ofstream *file) {
if (!file->is_open()) {
file->flush();
file->close();
}
};
std::unique_ptr<std::ofstream, decltype(deleter)> file(new std::ofstream(), deleter);
if (fileData == nullptr || fileName == nullptr) {
return;
}
if (size <= 0) {
return;
}
file->open(fileName, std::ios::out);
// do something.
if (false) {
return;
}
file->write(fileData, size);
}
#include <fstream>
#include <memory>
void Write(const char *fileData, size_t size, const char* fileName) {
auto deleter = [] (std::ofstream *file) {
if (!file->is_open()) {
file->flush();
file->close();
}
};
std::unique_ptr<std::ofstream, decltype(deleter)> file(new std::ofstream(), deleter);
if (fileData == nullptr || fileName == nullptr) {
return;
}
if (size <= 0) {
return;
}
file->open(fileName, std::ios::out);
// do something.
if (false) {
return;
}
file->write(fileData, size);
}
共享指针 std::shared_ptr
cpp
#include <memory>
struct Attribute {};
class Render {
public:
explicit Render(std::shared_ptr<const Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<const Attribute> attribute_ = nullptr;
};
class Factory {
public:
explicit Factory(std::shared_ptr<Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<Attribute> attribute_ = nullptr;
};
class Container {
public:
explicit Container(std::shared_ptr<Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<Attribute> attribute_ = nullptr;
};
std::shared_ptr<Attribute> MakeAttribute()
{
// do something.
return std::make_shared<Attribute>();
}
int main()
{
std::shared_ptr<Attribute> attribute = MakeAttribute();
std::unique_ptr<Render> render = std::make_unique<Render>(attribute);
std::unique_ptr<Factory> factory = std::make_unique<Factory>(attribute);
std::unique_ptr<Container> container = std::make_unique<Container>(attribute);
return 0;
}
#include <memory>
struct Attribute {};
class Render {
public:
explicit Render(std::shared_ptr<const Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<const Attribute> attribute_ = nullptr;
};
class Factory {
public:
explicit Factory(std::shared_ptr<Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<Attribute> attribute_ = nullptr;
};
class Container {
public:
explicit Container(std::shared_ptr<Attribute> attribute) : attribute_(attribute) {}
private:
std::shared_ptr<Attribute> attribute_ = nullptr;
};
std::shared_ptr<Attribute> MakeAttribute()
{
// do something.
return std::make_shared<Attribute>();
}
int main()
{
std::shared_ptr<Attribute> attribute = MakeAttribute();
std::unique_ptr<Render> render = std::make_unique<Render>(attribute);
std::unique_ptr<Factory> factory = std::make_unique<Factory>(attribute);
std::unique_ptr<Container> container = std::make_unique<Container>(attribute);
return 0;
}
弱引用计数指针 std::weak_ptr
cpp
#include <memory>
class Container;
class Manager {
public:
Manager(std::weak_ptr<Container> container) : container_(container) {}
~Manager() { std::cout << "~Manager" << std::endl; }
private:
std::weak_ptr<Container> container_;
};
class Container {
public:
~Container() { std::cout << "~Container" << std::endl; }
void SetManager(std::shared_ptr<Manager> manager)
{
manager_ = manager;
}
private:
std::shared_ptr<Manager> manager_ = nullptr;
};
int main() {
auto container = std::make_shared<Container>();
auto manager = std::make_shared<Manager>(container);
container->SetManager(manager);
return 0;
}
#include <memory>
class Container;
class Manager {
public:
Manager(std::weak_ptr<Container> container) : container_(container) {}
~Manager() { std::cout << "~Manager" << std::endl; }
private:
std::weak_ptr<Container> container_;
};
class Container {
public:
~Container() { std::cout << "~Container" << std::endl; }
void SetManager(std::shared_ptr<Manager> manager)
{
manager_ = manager;
}
private:
std::shared_ptr<Manager> manager_ = nullptr;
};
int main() {
auto container = std::make_shared<Container>();
auto manager = std::make_shared<Manager>(container);
container->SetManager(manager);
return 0;
}