Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
bool setupDirectX( HWND hWnd ) { HRESULT result; IDXGIFactory * factory; // Hier noch den normalen ptr benutzt result = CreateDXGIFactory( __uuidof( IDXGIFactory ), (void**)&factory ); if(!result) return false; std::unique_ptr<IDXGIAdapter> Adapter; IDXGIAdapter * pAdapter = Adapter.get(); // Kann man diese Zeile nicht rauslassen? result = factory->EnumAdapters( 0, &pAdapter ); //... } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
template <class T> class com_ptr { private: T* ptr; static void release(T* ptr) { if (ptr) ptr->Release(); } static void acquire(T* ptr) { if (ptr) ptr->AddRef(); } public: com_ptr(T* ptr = nullptr) : ptr(ptr) { } com_ptr(const com_ptr& p) : ptr(p.ptr) { acquire(ptr); } com_ptr(com_ptr&& p) : ptr(p.ptr) { p.ptr = nullptr; } ~com_ptr() { release(ptr); } com_ptr& operator =(const com_ptr& p) { acquire(p.ptr); release(ptr); ptr = p.ptr; return *this; } com_ptr& operator =(com_ptr&& p) { swap(*this, p); return *this; } void release() { release(ptr); ptr = nullptr; } T* operator ->() const { return ptr; } operator T*() const { return ptr; } friend void swap(com_ptr& a, com_ptr& b) { using std::swap; swap(a.ptr, b.ptr); } }; |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 |
// Legt einen neuen unique_ptr an, der mit nullptr (oder vor C++11 einfach 0, auch bekannt als NULL) initialisiert wird. std::unique_ptr<IDXGIAdapter> Adapter; // Legt einen neuen rohen Zeiger an, der mit dem Zeiger aus Adapter, also ebenfalls nullptr, initialisiert wird. IDXGIAdapter * pAdapter = Adapter.get(); // Lässt pAdapter auf den zurückgegebenen Adapter zeigen, NICHT jedoch Adapter result = factory->EnumAdapters( 0, &pAdapter ); // Nur pAdapter zeigt auf den zurückgegebenen Adapter // Adapter ist dagegen weiterhin nullptr, deshalb wird am Ende NICHTS freigegeben |
C-/C++-Quelltext |
|
1 2 3 4 5 |
T** rebind() { release(); return &ptr; } |
C-/C++-Quelltext |
|
1 2 |
com_ptr<IDXGIAdapter> Adapter; result = factory->EnumAdapters( 0, Adapter.rebind() ); |
Windows und DX API nutzen ihre eigenen Datentypen und sind überhaupt nicht für SmartPointers ausgelegt, es ist darum ein bisschen fragwürdig diese zu nutzen, ausserdem macht es nur Sinn SmartPointers zu nutzen wenn diese auch die effektiven Besitzer des Objektes sind, was ja mit der Factory nicht der Fall ist.
Der Sinn von SmartPointer ist das manuelle Aufrufen von delete zu verhindern. DX nimmt dir hier die Arbeit bereits ab.
C-/C++-Quelltext |
|
1 2 |
int A = 0; delete A; |
C-/C++-Quelltext |
|
1 |
std:.unique_ptr<T> hello = std:.make_unique(T); |
C-/C++-Quelltext |
|
1 |
std::unique_ptr<T> hello(new T); |
Ok ich hab mir schon gedacht das smartpointer mit den DX Typen nicht harmonieren da sie ja auch IUnknown erben.
Aber die letzte Frage in meinem Post besteht immernoch, wenn der smartpointer zerstört wird wie sieht dann der delete Aufruf aus? Bei std:unique_ptr<A> wäre doch das gleiche wie...
C-/C++-Quelltext
1 2 int A = 0; delete A;
oder? Richtig müsste man doch immer einen std::unique_ptr<A*> verwenden?
dots Klasse sollte im Regelfall keine Probleme machen; es gibt jedoch einige Fälle, in denen mit der impliziten Konvertierung unerwartetes Verhalten auftreten kann.
dots Klasse kannst du um eine Methode rebind() erweitern: [...]
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
com_ptr<ID3D11Buffer> vb = [](ID3D11Device* device, UINT buffer_size) -> ID3D11Buffer* { D3D11_BUFFER_DESC buffer_desc; buffer_desc.ByteWidth = buffer_size; buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; buffer_desc.StructureByteStride = 0; ID3D11Buffer* buffer; D3D11::checkError(device->CreateBuffer(&buffer_desc, nullptr, &buffer)); return buffer; }(device, buffer_size); |
C-/C++-Quelltext |
|
1 2 3 4 5 |
template <typename F> com_ptr(F f) // explicit? { f(&ptr); } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
com_ptr<ID3D11Buffer> vb([=](ID3D11Buffer** buffer) { D3D11_BUFFER_DESC buffer_desc; buffer_desc.ByteWidth = buffer_size; buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; buffer_desc.StructureByteStride = 0; D3D11::checkError(device->CreateBuffer(&buffer_desc, nullptr, buffer)); }); |
Dieser Beitrag wurde bereits 16 mal editiert, zuletzt von »dot« (18.07.2012, 23:05)
Zitat von »"dot"«
Jap, ich möchte nur meine com_ptr gern direkt wie normale Pointer an entsprechende Methoden übergeben und finde, dass in dem Fall die Vorteile bei weitem überwiegen.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »CodingCat« (19.07.2012, 10:55)
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
com_ptr<ID3D11Buffer> vb = [](ID3D11Device* device, UINT buffer_size) -> ID3D11Buffer* { D3D11_BUFFER_DESC buffer_desc; buffer_desc.ByteWidth = buffer_size; buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; buffer_desc.StructureByteStride = 0; ID3D11Buffer* buffer; D3D11::checkError(device->CreateBuffer(&buffer_desc, nullptr, &buffer)); return buffer; }(device, buffer_size); |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
com_ptr<ID3D11Buffer> vb([=](ID3D11Buffer** buffer) { D3D11_BUFFER_DESC buffer_desc; buffer_desc.ByteWidth = buffer_size; buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.MiscFlags = 0; buffer_desc.StructureByteStride = 0; D3D11::checkError(device->CreateBuffer(&buffer_desc, nullptr, buffer)); }); |
Werbeanzeige