Если я использую cpp без shared_ptr
, как управлять временем жизни экземпляра и односторонним владением? Существует ли какое-либо соглашение? Например, 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);
}