如何在没有shared_ptr的情况下管理cpp中的原始指针?

时间:2014-06-12 12:18:44

标签: c++ c shared-ptr

如果我使用不带shared_ptr的cpp,如何管理实例的生命周期和一对多的所有权?是否可以遵循任何惯例? 例如,DirectX在任何地方都有D3DDevice*D3DDeviceContext*,并且网格可以由sereval对象拥有。

把它交给经理来保持它的生命时间并且通过ref总是通过它,这可以是一个很好的解决方案吗?

C如何管理项目中的原始指针和所有权?

任何回复都将不胜感激。

1 个答案:

答案 0 :(得分:1)

简而言之,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;
};

中,故事是相同的,当引用计数变为零时,您必须维护引用计数并释放托管空间。 opaque pointer的示例如下:

<强> 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);
}