Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?
-
Allgemein gefragt, wann verwendet man smart pointer, also z.B.
std::unique_ptr
.Nur um heap-memory als Speicher zu verwenden? Oder gibt es noch andere Gründe?
Also ist ein verzögerter Konstruktoraufruf (wie im Titel) auch ein Grund, oder macht man das anders?
-
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
Also ist ein verzögerter Konstruktoraufruf (wie im Titel) auch ein Grund, oder macht man das anders?
Kommt drauf an, was du unter * verzögerter Konstruktoraufruf* verstehst. Du verwendest dann jedenfalls "Heapmemory".
Möglicherweise suschst du aber auch
std::optional
.
-
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
Allgemein gefragt, wann verwendet man smart pointer, also z.B. std::unique_ptr.
Nur um heap-memory als Speicher zu verwenden? Oder gibt es noch andere Gründe?wenn man mit pointern hantieren muss, aber sich vor fehlern fürchtet, die bei der benutzung roher pointer passieren können.
-
@manni66 Danke für die rasche Antwort.
Also unten ist
context
als smartpointer deklariert, um den Konstruktor verzögert (nach context_attributes) aufrufen zu können.Wenn ein Objekt von GLCanvas als smartpointer "angelegt" (definiert oder allokiert???) wird, dann sind doch sowieso alle member in der Klasse im heap-Speicher (unabhängig davon, ob sie als smartpointer deklariert sind)?
class GLCanvas : public wxGLCanvas { public: GLCanvas(Frame* parent, const wxGLAttributes& canvas_attributes); private: std::unique_ptr<wxGLContext> context; }; GLCanvas::GLCanvas(Frame* parent, const wxGLAttributes& canvas_attributes) : wxGLCanvas(parent, canvas_attributes) { wxGLContextAttrs context_attributes; context_attributes.PlatformDefaults().CoreProfile().OGLVersion(3, 2).EndList(); context = std::make_unique<wxGLContext>(this, nullptr, &context_attributes); std::cout << "context IsOK " << context->IsOK() << '\n'; }
Edit: @Bushmaster Danke für die rasche Antwort. Ja ich meinte auch rohe pointer mit
new
unddelete
, wo der Konstruktor mitnew
aufgerufen wird.
-
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
context = std::make_unique<wxGLContext>(this, nullptr, &context_attributes);
WxWidgets ist wirklich der letzte Schrott! Wenn der wxGLContext keine Kopie der Attribute macht (er nimmt einen Pointer, die Doku sagt nichts dazu), ist dein Objekt am Ende des Konstruktors kaputt.
Abgesehen davon:
auto defaultAttrs() { wxGLContextAttrs context_attributes; context_attributes.PlatformDefaults().CoreProfile().OGLVersion(3, 2).EndList(); return wxGLContextAttrs ; } class GLCanvas : public wxGLCanvas { private: wxGLContextAttrs context_attributes; wxGLContext context; }; GLCanvas::GLCanvas(Frame* parent, const wxGLAttributes& canvas_attributes) : wxGLCanvas(parent, canvas_attributes), context_attributes(defaultAttrs()), context(this, nullptr, &context_attributes)
So oder so ähnlich sollte es auch gehen.
Wenn du wirklich keine andere Wahl hast, wäre std::optional eine Alternative zu Pointern.
-
@manni66 Vielen Dank. Habe deinen Lösungsvorschlag übernommen und der context ist ganz, also das rendern funktionert
@manni66 sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
WxWidgets ist wirklich der letzte Schrott! Wenn der wxGLContext keine Kopie der Attribute macht (er nimmt einen Pointer, die Doku sagt nichts dazu), ist dein Objekt am Ende des Konstruktors kaputt.
Werden Konventionen nicht eingehalten? Sonst habe ich andere GUI-Libraries angeschaut (z.B. auch QT) und habe mich jetzt vorläufig für wxWidgets entschieden, es wird auch aktiv weiterentwickelt.
-
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
Werden Konventionen nicht eingehalten?
Es wird ein Pointer auf wxGLContextAttrs übergeben. Das macht man in C++ dann, wenn man sich diese Adresse merken will, statt das Objekt zu kopieren. Für Attribute ist das eine eher ungewöhnliche Vorgehensweise. Die Doku schweigt sich darüber aus.
-
@manni66 Habe im Quellcode gesucht. Ich verstehe es so, dass man auch
nullptr
übergeben können soll.
-
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
@manni66 Habe im Quellcode gesucht. Ich verstehe es so, dass man auch
nullptr
übergeben können soll.Man könnte zwei Konstruktoren anbieten, wenn der Parameter nur optional sein soll. Was auch immer: es wird nicht erklärt, was mit den Attributen passiert.
-
@Bushmaster sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
wenn man mit pointern hantieren muss, aber sich vor fehlern fürchtet, die bei der benutzung roher pointer passieren können.
-
@hustbaer sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
@Bushmaster sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
wenn man mit pointern hantieren muss, aber sich vor fehlern fürchtet, die bei der benutzung roher pointer passieren können.
du findest wohl smartpointer wenig sinnvoll. bist wohl ein oldschool-c-coder.
-
@Bushmaster Nein. Ich verwende ausschliesslich Smart-Pointer. Aber nicht weil ich Angst habe, sondern weil alles andere Quatsch ist.
-
@manni66 sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
context = std::make_unique<wxGLContext>(this, nullptr, &context_attributes);
WxWidgets ist wirklich der letzte Schrott! Wenn der wxGLContext keine Kopie der Attribute macht (er nimmt einen Pointer, die Doku sagt nichts dazu), ist dein Objekt am Ende des Konstruktors kaputt.
wxWidgets ist zwar manchmal etwas altbacken, aber Schrott ist es bei weitem nicht. Die meisten Dinge sind konsitent und ganz gut durchdacht. Es steht unter einer echten OpenSource Lizenz und braucht keinen spezial Compilier. Es gibt zwar immer mal Ecken, wo man sich etwas ärgert, aber an und für sich, kann man mit wxWidgets ganz brauchbar GUIs erstellen.
In dem Fall, werden die Attribute Kopiert (ich hab grade mal in die Sourcen geschaut).
Ist halt ein optionaler Parameter. Entweder muss man zwei Konstruktoren machen, einen für den Fall, dass man den Parameter nicht übergeben möchte und einen für die Übergabe, dann kann man eine const Referenz nehmen, oder man handelt das in einem Konstruktor ab, muss dann aber über den Pointer gehen um nullptr als Auswahl für nicht vorhanden zu erlauben.
Wenn man dahingehend die Doku verbessern kann, ist die wxWidgets Community bestimmt dankbar, wenn man da ein ein Vorschlag einreicht. Ist halt eine Community Sache, ohne eine Firma dahinter.
@Bushmaster sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
@titan99_ sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
Allgemein gefragt, wann verwendet man smart pointer, also z.B. std::unique_ptr.
Nur um heap-memory als Speicher zu verwenden? Oder gibt es noch andere Gründe?wenn man mit pointern hantieren muss, aber sich vor fehlern fürchtet, die bei der benutzung roher pointer passieren können.
Immer, wenn man mit rohen Pointern hantieren muss, die Objekte "besitzen".
-
@hustbaer sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
Nein. Ich verwende ausschliesslich Smart-Pointer.
ich verzichte ganz auf pointer und maschinennahe konzepte wie adressen. brauchste nicht in c++.
wird langsam zeit dass pointer rausfliegen. https://www.fluentcpp.com/2018/04/01/cpp-will-no-longer-have-pointers/
-
@Bushmaster
this article, released on April Fool date, was an April Fool joke.
Ja dann ist ja alles gut ...
-
@manni66 sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
this article, released on April Fool date, was an April Fool joke.
über sowas macht man keine witze!
-
@Bushmaster je mehr ich von dir lese meine ich dass du ausschliesslich witze machst. aber irgendwie komische. wenn du nie pointer verwendest, gut, in bestimmten anwendungen geht das schön. aber nicht überall. wenn du das nicht verstehst, dann fehlt dir vermutlich etwas die erfahrung über den tellerrand hinaus.
-
@hustbaer sagte in Verwendung von smart pointern nur um Konstruktoraufruf verzögern zu können?:
wenn du nie pointer verwendest, gut, in bestimmten anwendungen geht das schön. aber nicht überall. wenn du das nicht verstehst, dann fehlt dir vermutlich etwas die erfahrung über den tellerrand hinaus.
Wenn man nur stack-memory verwendet?
Edit: Glaube doch nicht, weil z.B. vector auch heap-memory verwendet.
-
EDIT: Falschen Thread erwischt
-
//Note: // You may wonder why OpenGL initialization was not done at wxGLCanvas ctor. // The reason is due to GTK+/X11 working asynchronously, we can't call // SetCurrent() before the window is shown on screen (GTK+ doc's say that the // window must be realized first). // In wxGTK, window creation and sizing requires several size-events. At least // one of them happens after GTK+ has notified the realization. We use this // circumstance and do initialization then.
Also es gibt eine zweite Verzögerung bzw. ein Aufruf während der Initialization, die aber erst nach bestimmten anderen Aufrufen geschehen kann.
GetParent()->Show(); SetCurrent(context); int gladLoaded = gladLoadGL();
Also das Fenster muss angezeigt sein, erst dann sollte der OpenGL context SetCurrent übergeben werden und erst danach kann glad (in dem Fall) oder glew initialisiert werden. Und erst danach kann die GraphicEngine allokiert werden.
graphic_engine = std::make_unique<GraphicEngine>(); graphic_engine->Setup();
Die Verzögerung ist immer noch durch smartpointer bzw.
new
ermöglicht. Wird GraphicEngine vor gladLoadGL() allokiert, kommt beim ersten(?) OpenGL-Funktionsaufruf -glGenVertexArrays(1, &VAO);
eine Fehlermeldung: Access violation executing location 0x0000000000000000.