[Demande de conseils] Wrapper C++ pour la SDL2

a marqué ce sujet comme résolu.

Je te sors l’essentiel du code plus ou moins de tête (je suis au boulot, je n’y ai pas accès) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
struct Rect final :
  public ecs::Component,
  private SDL_Rect
{
  Rect(int coordX, int coordY, int width, int height) noexcept
    : x(coordX), y(coordY), w(width), h(height) {}
  using SDL_Rect::x;
  using SDL_Rect::y;
  using SDL_Rect::w;
  using SDL_Rect::h;
};

Mon compilo est VS2015.

Mais en fait il semblerait que ça n’ait rien à voir avec le fait que SDL_Rect est un type C ; je crois que c’est juste parce que je veux initialiser x, y, w et h dans la liste d’initialisation du constructeur de sdl::Rect. J’ai pu reproduire un cas similaire (lien ici) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
struct Foo {
  Foo() = default;
  int i;
};

struct Bar : private Foo {
  Bar(int x) : i(x) {}
  using Foo::i;
};

// main.cpp:7:16: error: class 'Bar' does not have any field named 'i'

Si l’on suit cet exemple, la solution serait :

1
2
3
Bar::Bar(int x) {
  i = x;
}

Que l’initialisation pose problème, ça me semble tout à fait cohérent et la solution est simple :

1
2
3
4
5
6
/*
Rect(int coordX, int coordY, int width, int height) noexcept
    : x(coordX), y(coordY), w(width), h(height) {}
*/
Rect(int coordX, int coordY, int width, int height) noexcept
    : SDL_Rect{ coordX, coordY, width, height } {}

@GaaH : Aurais-tu un exemple d’utilisation applicable dans ce contexte ? J’avoue avoir un peu de mal à l’imaginer :/

vincentp

Un truc du genre :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Width
{
    public Width(int width)
   {
        if (width < 0 || width > MAX_WIDTH)
        {
            // gère l'erreur
        }

        this.value = width;
   }
};

Avec ta classe Rect définissant un constructeur prenant en paramètre des objets de type Width et Height.

Et du coup, c’est pas ta classe Rect qui gère ton problème de taille, mais plutôt l’objet que tu lui passe en paramètre. Du coup, tu a l’assurance que les objets passé en paramètres sont valides.

Le lien que je te fournis propose une façon générique de définir les types Width et Height.

J’aime bien l’idée, mais si l’on garde l’idée de ne pas dupliquer les données, on arrive vite à une situation proche de :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
struct Rect final : private SDL_Rect {
  Rect(int x, int y, Width w, Height h) : SDL_Rect{x, y, w.get(), h.get()} {}
  // ^ Si c'est juste pour l'initialisation, on peut aussi passer par unsigned + static_cast
  // ...
  using SDL_Rect::x;
  using SDL_Rect::y;
  using SDL_Rect::w;
  using SDL_Rect::h;
  operator SDL_Rect() const noexcept;
};
// ...
Rect rect{0, 0, 10, 10}; // Ok, les valeurs sont valides
rect.w = -10;            // C'est bête, mais valide

On laisse donc le soin à l’utilisateur de ne pas faire n’importe quoi ?

EDIT : Il semblerait que le problème se règle de lui-même : error: cannot cast 'X' to its private base class 'Y'. Je préfère garder la possibilité de convertir sdl::Rect en SDl_Rect, sdl::Point en SDL_Point, etc… (tant qu’il n’y a pas de pointeur en variable membre) Donc je pense virer l’héritage privé, et retour à la case départ.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte