Du bist nicht angemeldet.

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

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

1

16.05.2015, 19:16

Eigenschaft vor/beim Erzeugen angeben

Mir fiel leider kein besser Titel ein. ;)

Ich überlege mir gerade eine Design-Lösung und würde gerne eure Meinungen und weiteren Input hören.
Und zwar habe ich eine Surface struct die mehr oder minder eine SDL_Surface* wrappt.

Beim Erstellen einer SDL_Surface kann man angeben, wie die Masken für Rot, Grün Blau und Transparenz definiert werden sollen (jeweils ein uint). Das ganze wrappe ich in einer struct Masks.
Diese Masken müssen nur für Spezialfälle definiert werden (z.B. wenn ich eine Transparente Grafik brauche). Ansonsten kann/könnte ich auf eine Default Version zugreifen, wo alle Masken 0 sind (oder eben 0xffffffff, je nachdem was öfter zutrifft).
Nun geht es darum, wie ich das der Surface sozusagen injecten kann. Ich habe mehrere mögliche Lösungen die ich aber irgendwie alle nicht so ganz toll finde:

1. Das Ding einfach im CTor übergeben. Wird bisher gemacht, ist das einfachste bläht aber IMO den CTor so auf. Damit sind es vier Parameter für den CTor, neben Breite, Höhe und Tiefe.
2. Als static Member halten. Default hat es einen Wert, soll der sich ändern, muss dieser vor dem Erstellen eben angepasst werden. Nachteil: wirkt sich natürlich ab da an auf _alle_ folgenden Instanzen aus. Ich könnte es nach der Benutzung wieder auf dem Default Wert resetten, aber ich weiß nicht ob das ganze im Sinne des Erfinders ist.
3. Eine Art Config struct einführen. Darin befinden sich dann alle vier Parameter und die struct hält auch direkt Default Werte für solche, die sich nur selten ändern und nicht immer mit angegeben werden sollen/müssen (auch wenn das in diesem Fall nur der eine ist). Dann wird die angepasste Config an den CTor übergeben. Wirkt auf mich irgendwie, als würde man das Problem nur verschieben.

Was schlagt ihr vor, oder habt ihr noch eine bessere/andere Idee?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

2

16.05.2015, 19:35

Die 2. Methode aufjedenfall nicht ;) Aber methode 3 passt doch. Unnötig aufblähend ist da nichts, wenn die klasse es braucht dann muss man es halt übergeben.

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

3

16.05.2015, 19:37

Methode 3 empfinde ich als Auslagerung des eigentlichen Problems, nicht aufblähend. :)
Denn dann hat die Config struct eben alle Parameter.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

4

16.05.2015, 19:43

Na irgendwo musst du diese Werte ja übergeben ;)

5

16.05.2015, 23:21

Sehe ich das richtig, dass dein einziges Problem die große Anzahl der Konstruktorparameter ist, und dass man das nicht mit default Werten in den Griff bekommen kann, weil man mal die einen, mal die anderen angeben möchte?

Dann schreib dir doch einfach einen 'variadic' Konstruktor. (Wie ich feststellen musste, steht 'variadic' in keinem Wörterbuch, weil es eigentlich aus 'variable' und 'arity' zusammengesetzt ist). Nicht dass ich das schonmal gemacht hätte, aber im Grunde wäre dein Konstruktor dann ein template und jeder Parameter bräuchte einen eindeutigen Typen. Was aber extrem einfach geht, indem du dir ein template baust, dass einfach nur einen Wert speichert und diesen zurückgibt und dann für jeden Konstruktor-Parameter davon eine Klasse ableitest.

Aufrufen würdest du das ganze dann später so:

C-/C++-Quelltext

1
MyClass(Height(200), Width(15), SomeValue(5), AnotherValue(-4));

Wobei die Reihenfolge und Anzahl der Parameter vollkommen egal wäre.

Ich bin mir gerade nicht komplett sicher, ob das mit delegate constructors geht, wenn nicht musst du evtl. eine Funktion basteln, die dann das Objekt erzeugt und zurückliefert.


Ooooder du lässt den ganzen variadic-Kram weg und baust die Standardwerte in die Parametertemplates ein. Ein Aufruf sähe dann so aus:

C-/C++-Quelltext

1
MyClass(Height(200), Width(250), SomeValue::default(), AnotherValue(4));

d.h. die Reihenfolge ist statisch, man muss immer alle Parameter angeben, aber kann immer ::default schreiben, wenn man den Wert nicht explizit setzen will.


Wobei ich sagen muss, dass beide Methoden den Konstruktor-Code ziemlich aufblähen und es halt eine komische Art ist, Konstruktoren aufzurufen. Weiß nicht, ob es das wert ist...
Lieber dumm fragen, als dumm bleiben!

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

6

16.05.2015, 23:44

Irgendwie eine nette Idee. :) Ja mein einziges Problem ist eig. ob ich den CTor unbedingt aufblähen sollte oder ob das vllt. nicht eine elegantere Lösung gibt, man lernt ja nie aus. Deine Lösung ist eig. ziemlich cool, aber ich glaube etwas "too much". Aber ich werd' mal damit rumspielen, vielen Dank. :)
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

7

17.05.2015, 00:09

Ich glaube, es ist eine sehr schöne Übung um zu sehen, was man mit C++ so alles machen kann. Aber es ist halt eine sehr komische Art der Parameterübergabe, die wirklich nicht intuitiv ist, und man schreibt einiges an Code, der eigentlich gar nichts macht.

Die einfachste und schnellste Art ist vermutlich, eine Initialisierungsstruktur zu benutzen, deren Standardkonstruktor alle Werte auf ihren Standard setzt. Kann man dann auch recht kompakt schreiben:

C-/C++-Quelltext

1
2
3
MyClass::P p;
p.Width=512; p.Height=9; p.AnotherParameter=9;
auto object = MyClass(p);

Sieht auch nicht soo schlimm aus, und jeder versteht es sofort.
Lieber dumm fragen, als dumm bleiben!

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

8

17.05.2015, 01:40

Was meiner 3. Lösung entspräche, oder nicht?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

9

17.05.2015, 01:49

Ich würde vielleicht sogar folgendes Konstrukt benutzen:

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
struct Dimension
 {
    std::size_t width {800ULL};
    std::size_t height {600ULL};
};

struct Preferences
{
    friend class A;
public:
    Preferences() = default;

    template<class ...T>
    Preferences(T... t)
    { init(t...); }
private:
    template<class ...T>
    void init(Dimension d, T... t)
    { this->d = d; init(t...); }

    template<class ...T>
    void init(std::string s, T... t)
    { this->s = s; init(t...); }

    void init()
    {}
private:
    Dimension d {800ULL, 600ULL};
    std::string s {"hello world"};
    //...
};

class A
{
public:
    template<class ...T>
    A(T... t) : pref(t...)
    {std::cout << pref.d.width << "\t" << pref.d.height << "\t" << pref.s << std::endl;}
private:
    Preferences pref;
};

So hat man den ganzen Template-Kram ganz gut abgetrennt von dem, wo es an sich nicht gebraucht wird, verzichtet aber trotzdem nicht auf die variable Parameterliste.
Btw auch online! (gefixt)

MfG
Check

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Checkmateing« (17.05.2015, 13:29)


Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

10

17.05.2015, 11:00

Kaputter Link. ;) Und: GCC 5.1? Unter 4.9.2 und 5.0 Beta gibt es nur Fehler. :D
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Werbeanzeige