как управлять необработанными указателями в cpp без shared_ptr?

0

Если я использую cpp без shared_ptr, как управлять временем жизни экземпляра и односторонним владением? Существует ли какое-либо соглашение? Например, DirectX имеет D3DDevice*, D3DDeviceContext* везде, а сетка может принадлежать объектам-объектам.

Поместите его менеджеру, чтобы сохранить его время жизни и всегда передавать его по ref, может ли это быть хорошим решением?

И как C управляет необработанным указателем и собственностью в проекте?

Любой ответ будет оценен.

  • 2
    Язык не будет ничего делать, вы делаете это. Подумав, что можно удалить, когда и почему.
  • 4
    Определите свою собственную структуру RAII.
Показать ещё 5 комментариев
Теги:
shared-ptr

1 ответ

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

В история такая же, вам нужно сохранить счетчик ссылок и освободить управляемое пространство, когда счетчик ссылок станет нулевым. Пример с непрозрачным указателем может быть следующим:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню