• 博客
  • 音乐
  • 随想
  • 足迹
  • 关于
  • 个人空间
    • 登录
animals
    bg
    智能指针的应用
    所属分类:c++
    发布时间:2025-05-19 10:03

    c++中智能指针的应用

    涉及到的头文件包括<memory>

    独占指针 std::unique_ptr

    独占指针是一种带有所有权的智能指针

    在私有成员中使用:

    #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 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 <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

    #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

    #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

    #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;
    }