J'aimerais créer une classe qui peut (doit en faites!) être surchargez avec un tableaux de "Tile" (Classe) de 100*100, donc multi-dimensionnel, mais voilà : peu importe ce que j'essaye de faire, le compilateur me crache dessus :/, voici TRÈS GROSSIÈREMENT ce que j'essaye de réaliser :
En ce qui concerne ma notation, c'est le "s" de "settings" juste parce que voilà...Pour un 1er programme je préfère me gérer solo, mais je sais très bien qu'un jour je changerais toute la notation. Bref! Je ne suis pas assez avancez en C++ pour connaître les template, il n'y aurais pas plus simples? Parce que je veux juste un tableaux dans une classe ^^' hein...
"s_", c'est généralement un vielle notation pour des champs statiques, selon les conventions de nommage "hongroise".
Tu peux pas le deviner, mais c'est bien de ne pas trop mélanger les notations.
Le fait de "marquer" qu'un paramètre d'une fonction vient de "settings", c'est pas très pertinent.
La fonction "fonctionnera" que la source des arguments soit un "settings" ou tout autre chose.
Ne pas surcharger les notations avec des trucs inutiles.
>mais je sais très bien qu'un jour je changerais toute la notation
Autant prendre directement les bonnes habitudes, prend une convention de nommage C++ (attention les conventions de nommages sont spécifiques à un langage), comme celle de Google ou autre.
Si elles existent, c'est qu'elles ont un intérêt non négligeable, comme ne pas surcharger les notations avec des trucs inutiles. ;-)
>Je ne suis pas assez avancez en C++ pour connaître les template
C'est pas grave. Oui, c'est un topics avancé pour en fabriquer un, mais les utiliser, c'est très simple. std::string est déjà un template mais c'est une classe "de base" du C++.
> il n'y aurais pas plus simples?
S'en servir, c'est largement de qu'il y a de plus simple.
>Parce que je veux juste un tableaux
Les tableaux C, c'est de la merde, ça oblige à utiliser des pointeurs nus tout pourri, à faire les copies "à la main", des allocations qui vont fuir, la stack qui va exploser, etc...
En utilisant le template de Warren79, c'est nettement plus simple :
Et dans tout ce code, la copie, les allocations, les libérations, la gestion d'une taille variable de map, etc... est déjà pris en compte "gratuitement".
Considère "MatrixTemp2D" comme ton "tableau", mais en largement mieux qu'un tableau C à 2 dimensions.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Revenons sur le sujet, la question n'est pas la haine nécessaire envers les tableaux et l'adoration qu'on doit porter respectueusement aux templates - les pointeurs intelligents sont absents pour une fois - , mais une histoire d'initialisation d'une donnée membre de type "tableau".
Simplifions : si on écrit
class C {
private:
int m_t[10];
public:
C(int t[10]) :
m_t {t} // erreur compilation
{}
};
On se traine une erreur de compilation dans la liste d'initialisation parce que, en gros, on ne peut pas affecter un tableau "style C" dans un autre. Pas possible de faire m_t = t;
Raison : un tableau, c'est -approximativement- l'adresse d'un emplacement contenant les cases, et que affecter l'adresse, c'est pas affecter les cases.
Mais bon, on peut faire autrement, avec une donnée membre qui est un pointeur et non un tableau
class C {
private:
int *m_t; // changement
public:
C(int t[10]); // ok
};
Attention, ça ne stockera pas une _copie_ du contenu du tableau, donc il y aura des précautions à prendre sur la durée de vie des données.
Ca va se compliquer avec un tableau 2d. On peut s'en sortir comme ça
typedef int ligne[10];
class C {
private:
ligne * m_t;
public:
C(ligne t[10])
: m_t {t}
{}
};
ou comme ça
typedef int mat[10][10];
class C {
private:
mat & m_t;
public:
C(mat & t)
: m_t {t}
{}
};
(manque de temps, non testé à l'exécution).
PS:
Enfin, ce n'est pas une bonne idée de réinventer une classe Matrice, alors qu'il suffit d'utiliser la bibliothèque standard et un brave alias.
using Mat3x3 = std::array< std::array<float, 3> 3>;
Mat3x3 m ;
m[1,2] = 3.14;
ou, pour des matrices carrées génériques
template <typename T, int N>
using Mat = std::array< std::array<T, N>, N>;
Mat<bool, 10> m;
m[3][8] = true;
- Edité par michelbillaud 24 janvier 2019 à 13:42:33
Et pour les matrices pleines mais pas forcément carrées (genre : 9 lignes de 4 colonnes), on peut utiliser un alias proche de
template <typename T, int L, int C>
using Mat = std::array<std::array<T, C>, L>;
Par contre, il faudra toujours prendre en compte qu'une matrice, c'est un ensemble de Lignes * Colonnes éléments qui sont-- a priori -- contigus en mémoire, et qui nécessite donc un espace mémoire proportionnel non seulement à la taille des éléments qu'il faut représenter, mais aussi au nombre de lignes et au nombre de colonnes que l'on souhaite représenter.
Or, un tel alias de type est tout à fait susceptible de prendre place dans la pile d'appels, qui est un espace mémoire pour le moins limité (rarement plus de 1 à 2 Mb ). Le risque de saturer la pile en essayer d'y faire entrer plus de données que ce qu'elle n'est capable d'en contenir est donc particulièrement présent. Et ca, ca représente une situation catastrophique.
Il est donc particulièrement conseillé de trouver le moyen de s'assurer que l'espace mémoire nécessaire à la représentation de tous les éléments d'une matrice soit pris sur le tas au lieu de sur la pile, principalement lorsque nous avons affaire à des matrice importantes (une matrice de 3*3 ou de 4*4 int ou double ne posera pas trop de problème, une matrice de 150*200 données complexes en posera beaucoup plus )
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Et une matrice creuse ne se represente généralement pas par un tableau.
Donc, ca dépend.
Et pour des petites tailles, array d'array ca va très bien. Pas de surcoût lié aux indirections, pas de coût de gestion des libérations, localité des données, c'est bon pour le cache.
- Edité par michelbillaud 25 janvier 2019 à 7:58:54
Et pour des petites tailles, array d'array ca va très bien. Pas de surcoût lié aux indirections, pas de coût de gestion des libérations, localité des données, c'est bon pour le cache.
Ah je ne dis absolument pas le contraire! Je dis juste que cela a beau être bon pour le cache, ca peut devenir nocif pour la pile d'appels
Et c'est la raison pour laquelle, "au delà d'un certain point", il s'avère préférable -- lorsque l'on a affaire à des matrice pleines -- d'envisager la linéarisation des données, et donc, la mise ne place d'une notion de Matrice plus "consistante"
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
- Dans l'exemple donné, matrice 100x100 de Tiles, soit 10 000 éléments.
- Taille standard de la pile (sous linux)
$ ulimit -a
...
stack size (kbytes, -s) 8192
8 megas (mais ça peut se changer, bien sûr). Il m'en faut plus ? ulimit -s xxxxx
- sizeof(Tile) ? Inconnu.
- combien de Map présente en mémoire quand le programme tourne ? une, quelques unes, plusieurs, beaucoup, énormément ? On ne sait pas.
Donc pas de conclusion à tirer sur ce point, sinon qu'en général "il faut faire attention à ce qu'on fait" :-)
Et la question d'origine n'était pas de discuter la meilleure façon de représenter un tableau 2D, mais de voir comment on pouvait initialiser un tableau 2D dans un constructeur. Faut pas se laisser égarer par ses lubies.
- Edité par michelbillaud 25 janvier 2019 à 19:40:43
Surcharger une classe avec un tableau?
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Mon site web de jeux SDL2 entre autres : https://www.ant01.fr