如何管理原始指针在CPP没有shared_ptr

how to manage raw pointers in cpp without shared_ptr?

本文关键字:CPP 没有 shared ptr 指针 原始 何管理 管理      更新时间:2023-10-16

如果我使用没有shared_ptr的cpp,如何管理实例的生命周期和一对多所有权?有什么惯例可以遵循吗?例如,DirectX到处都有D3DDevice*, D3DDeviceContext*,网格可以由多个对象拥有。

把它放到一个管理器来保存它的生命时间,并且总是通过ref传递它,这是一个好的解决方案吗?

和C如何管理原始指针和所有权在一个项目?

欢迎回复

简而言之,std::shared_ptr与它的所有副本一起保持引用计数对其包含的指针的所有权。这意味着几个std::shared_ptr对象可以通过指针拥有同一个对象。当拥有该对象的最后一个std::shared_ptr被销毁或被分配另一个指针时,上述对象将被销毁。

您可以使用RAII实现相同的功能,如下所示:
template<typename T> class MySharedPtr {
public:
    MySharedPtr() : ref_count(new int(1)), obj_ptr(0) {
    }
    MySharedPtr(T* new_ptr) : ref_count(new int(1)), obj_ptr(new_ptr) {
    }
    MySharedPtr(const MySharedPtr<T>& other) :
            ref_count(other.ref_count), obj_ptr(other.obj_ptr) {
        (*ref_count)++;
    }
    ~MySharedPtr() {
        if(--(*ref_count) == 0) {
            delete ref_count;
            delete obj_ptr;
        }
    }
    MySharedPtr<T>& operator=(const MySharedPtr<T>& other) {
        if(this != &other) {
            if(--(*ref_count) == 0) {
                delete ref_count;
                delete obj_ptr;
            }
            ref_count = other.ref_count;
            obj_ptr = other.obj_ptr;
            (*ref_count)++;
        }
        return *this;
    }
    T& operator*() { return *obj_ptr; }
    T* operator->() { return obj_ptr; }
private:
    int* ref_count;
    T* obj_ptr;
};

在c中情况是一样的,您必须维护引用计数并在引用计数变为零时释放托管空间。使用不透明指针的示例如下:

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H
struct MyType;
struct MyType* new_MyType();
struct MyType* ref_MyType(struct MyType*);
struct MyType* unref_MyType(struct MyType*);
float MyType_getData(struct MyType*);
#endif /* EXAMPLE_H */

example.c

#include "example.h"
#include <stdlib.h>
struct MyType {
    int ref_count;
    float some_data;
};
struct MyType* new_MyType() {
    struct MyType* obj_ptr = (struct MyType*)malloc(sizeof(struct MyType));
    obj_ptr->some_data = 0.0f;
    obj_ptr->ref_count = 1;
}
struct MyType* ref_MyType(struct MyType* obj_ptr) {
    if(obj_ptr == NULL)
        return NULL;
    obj_ptr->ref_count++;
    return obj_ptr;
}
struct MyType* unref_MyType(struct MyType* obj_ptr) {
    if(obj_ptr == NULL)
        return NULL;
    if(--(obj_ptr->ref_count) == 0) {
        free(obj_ptr);
        return NULL;
    }
    return obj_ptr;
}
float MyType_getData(struct MyType* obj_ptr) {
    return (obj_ptr != NULL ? obj_ptr->some_data : 0.0f);
}