2016-09-07 1 views
0

En C++, j'ai une classe qui contient un tableau 3d de type défini. J'ai besoin de définir plusieurs attributs qui ont une valeur de int et être en mesure de définir et d'obtenir les attributs pour 3d array.Définition d'attributs setter/getter pour un tableau 3D

//header; 
    class Voxel 
    { 
     private: 
     vector< vector < vector < myPoints* > > > Vox; // 3D array 
     public: 
     //... 
    }; 

    //Here is the constructor and methods of the class: 
    Voxel::Voxel(myType var1; double var2) 
    { 
    // this is constructor 

    } 

Par exemple, je dois définir « attributs » comme celui-ci qui ont des valeurs int:

Attributes: 
LabelTag; // Vox tag e.g. an int tag=2 
NumberofPoints; // Vox nr of containing points e.g. int nr=5 


Vox.setAttribute(LabelTag tag, Value 2); 
Vox.setAttribute(NumberofPoints nr, Value 5); 

int tag  = Vox.getAttribute(LabelTag); 
int nrofpoints = Vox.getAttribute(NumberofPoints); 

Comment dois-je définir les attributs, comme struct ou comme typedef ou autre chose, et comment Puis-je définir les valeurs de mes membres de tableau 3D par exemple Vox, Je veux définir des attributs pour le Vox lui-même, pas les points à l'intérieur? C'est possible? Et devrait-on les définir comme privé ou public?

+5

Vous stockez des pointeurs, donc pour y accéder vous utilisez la syntaxe "arrow" 'Vox [i] [j] [k] -> getAttribute()' – StoryTeller

+0

Dites-nous, quelle est l'utilisation de LabelTag et NumberOf Points? Vous pouvez stocker un point par vecteur, de sorte que vous avez 3 points dans un tableau 3D. – pospich0815

+0

@ pospich0815, c'est une tentative d'utilisation astucieuse (peut-être) de l'envoi de tags. Une spécialisation de template peut être meilleure 'getAttribute

Répondre

1

Edited answer below the second block of code.

Ok, tout d'abord comme commenté par @StoryTeller, votre vecteur stocke des pointeurs; vous devrez donc utiliser la syntaxe -> pour accéder à l'objet vers lequel ils pointent.Par conséquent, vous devriez probablement configurer une classe myPoints car les structures ne sont pas courantes (les structures en C++ sont la même chose qu'une classe sauf que le modificateur d'accès par défaut de leurs propriétés et fonctions est public). J'imagine cette classe pour ressembler à quelque chose comme

class myPoints // you should probably split this into a header and cpp 
{ 
    int tag; 
    int noOfPoints; 

    myPoints() : tag(0), noOfPoints(0) // construct with whatever values, you can pass your own 
    {} 

    void setNoOfPoints(noOfPoints) 
    { 
     this->noOfPoints = noOfPoints; 
    } 

    void setTag(tag) 
    { 
     this->tag = tag; 
    } 

    int getNoOfPoints(){ return noOfPoints; } 
    int getTag(){ return tag; } 
}; 

En supposant que vous avez initialisé avec quelques * vox MyPoints littéraux vous pouvez accéder simplement et utiliser vos objets MyPoints comme suit

int tag = Vox.at(i).at(j).at(k)->getTag(); 
int noOfPoints = Vox.at(i).at(j).at(k)->getNoOfPoints(); 

Vox.at(i).at(j).at(k)->setNoOfPoints(6); 
Vox.at(i).at(j).at(k)->setTag(6); 

Laissant ci-dessus répondez, comme pour la réponse de @ Aconcagua, vous pourriez le trouver utile à l'avenir. Quoi qu'il en soit, je pense que je comprends un peu mieux ce que vous essayez de faire, étant donné le code que vous avez déjà écrit comme @StoryTeller a dit, vous pouvez simplement utiliser votre classe Voxel pour contenir les propriétés tag et noOfPoints pour chaque vecteur . La classe Voxel ressemblera à quelque chose comme (pardonnez ma paresse de ne pas fournir un en-tête)

class Voxel 
{ 
private: 
    vector< vector < vector < myPoints* > > > Vox; 

    int tag; 
    int noOfPoints; 
public: 
    Voxel() : tag(0), noOfPoints(0) // construct with whatever values, you can pass your own 
    {} 

    vector< vector < vector < myPoints* > > >& getVox(){ return Vox; } //Ignore my shitty naming scheme, you can use this to set or get elements 

    void setNoOfPoints(noOfPoints) 
    { 
     this->noOfPoints = noOfPoints; 
    } 

    void setTag(tag) 
    { 
     this->tag = tag; 
    } 

    int getNoOfPoints(){ return noOfPoints; } 
    int getTag(){ return tag; } 
}; 

et d'accéder à votre vecteur et de définir votre étiquette et noOfPoints, créez simplement une instance de voxel, il devrait ressembler à ceci

//A new vector of voxels 

vector<Voxel> voxels; 

voxels.push_back(Voxel); // this only needs to be a 1d array, you can construct each voxel however you like and add as many as you like 

//settting the tag for the first element 

voxels[0].setTag(0); 

//getting the tag for the first element 

int tag = voxels[0].getTag(); 

// manipulating the contained vector 

voxels[0].getVox().at(i).at(j).at(k) = //whatever you are storing in your vector 
+0

cette réponse est proche de ce dont j'ai besoin, mais comme j'ai édité la question, est-il possible d'attribuer ces attributs au Vox lui-même pas les points à l'intérieur. Parce que myPoints peut avoir différentes valeurs par point, mais Vox qui contient ces myPoints peut obtenir une valeur par "Attribut". Ou imaginez que certaines des Vox sont vides mais je peux quand même leur attribuer quelques attributs. – Bruce

+0

C'est possible! En fait, comme vous l'avez indiqué, vous étiez sur la bonne voie avec votre classe Voxel, j'ai édité ma réponse, j'espère que ça aide :) – George

+0

Merci, j'ai implémenté votre code et il est assez proche de ce que je recherche. Juste je ne comprends pas une chose importante, quand j'affecte par ex. "tag attribut" avec 'i_Voxel.setTag (6)' il le définit à quoi? !! Je suppose à une instance de 'Voxel' mais comment devrais-je savoir à quel vecteur de Vox il a été défini. Disons que j'ai une boucle à travers tous les vecteurs et que je veux définir une étiquette pour chaque vecteur. Pourriez-vous expliquer comment cela fonctionne? – Bruce

0

Edit: Voir la réponse de George Purcell, je aurais peut-être mal compris vous la question, pensé qu'il était sur l'accès aux points de l'extérieur de la classe Voxel ...

Au lieu de supprimer la réponse, bien que, je laisse encore ici pour le cas où vous rencontrez ce problème tout plus tard et trouvent utile puis ...


Outre le problème pointeur StoryTeller déjà noté, vous avez un peu problème:

Vous pouvez simplement définir un opérateur d'index, mais cet opérateur d'index serait alors forcé de renvoyer une référence à un vector<vector<myPoints*>> (un vecteur de moins) ou un vector<vector<vector<myPoints*>>>::iterator.

Cela permettrait cependant à l'utilisateur de modifier les vecteurs sous-jacents, par exemple. g. les effacer. Si vous renvoyez maintenant const vector ou const_iterator, l'utilisateur ne pourra pas modifier la valeur stockée (appel de setAttribute ...). De plus, il pourrait jeter const loin, au moins dans le premier cas, puis faire à nouveau ce qu'il voulait ...

Alors vous avez deux options:

  1. Vous écrivez une fonction de lecture explicite:
    mypoints* getPoints(int x, int y, int z) { return vox[x][y][z]; }
  2. Vous enveloppez les vecteurs dans des classes distinctes. Ensuite, chaque classe peut fournir un accès approprié à son vecteur sous-jacent et en même temps empêcher l'utilisateur de faire des choses illégales. Chacun de ces cours fournirait alors son propre opérateur [], le même que fera votre classe externe Voxel:

class Voxel 
{ 
public: 
    class Points1D 
    { 
     vector<myPoints*> points; 
    public: 
     myPoints* operator[](unsigned int index) { return points[index]; } 
    }; 
    class Points2D 
    { 
     vector<Points1D> points; 
    public: 
     Points1D& operator[](unsigned int index) { return points[index]; } 
    }; 
    Points2D& operator[](unsigned int index) { return points[index]; } 
private: 
    vector<Points2D> points; 
}; 

Si vous voulez être en mesure de parcourir vos cours, vous devrait également fournir des itérateurs appropriés, et éventuellement d'autres choses (par exemple, la fonction size()) - en fonction de ce que l'utilisateur doit pouvoir faire avec vos classes ...

0

peut-être que ce n'est pas une réponse à votre question, mais il semble que vous avez venu du monde C# -kind, donc tu me laisses clarifier certaines choses (je l'espère, vous serez en mesure de reformuler votre question, afin que le programmeur C++ ordinaire puisse comprendre :)

Le concept des attributs a complètement différent meaning en C++ (je pense sans rapport avec ce que vous voulez implémenter)

Il n'y a pas non plus de concept séparé de propriétés (aka getters/setters) en C++. Au lieu de cela, vous écrivez simplement les fonctions membres getSmth() ou setSmth (type arg). Leur but est simplement de donner à un utilisateur un accès contrôlé aux variables membres privés. Cependant, ces fonctions sont simplement fonction de membre régulier avec des capacités maintenant spéciales.

Si vous souhaitez obtenir/définir une variable membre dit « tag » de la classe disent « myPoint » vous devez définir une fonction membre

class myPoint 
{ 
private: 
    int tag; 
//... 
public: 
    int GetTag(); 
    { 
     return tag; // return this->tag; 
    } 

    void SetTag(int t) 
    { 
     tag = t; 
    } 
} 

Ensuite, vous pouvez écrire

int main() 
{ 
    vector<vector<vector<myPoint*>>> Vox; 
    Vox[1][2][3]->SetTag(10); 
    cout << Vox[1][2][3]->GetTag(); 
} 

Cependant disons que vous avez quelques getters/setter pour différentes variables. Ensuite, il n'y a aucun moyen d'écrire

Vox[1][2][3]->GetAtribute(tag); 

et attendre compilateur pour comprendre que « oh, il a besoin d'obtenir une valeur de variable membre tag ». Dans le système de classes C++, seules les variables membres et les fonctions membres peuvent être utilisées. Tout est aussi simple que cela :)

Il est intéressant de pouvoir paramétrer n'importe quelle fonction non seulement avec des valeurs, mais aussi avec des types. Ensuite, vous serez en mesure de créer un modèle de fonction et d'appeler une version différente de la même fonction en fonction du type que vous avez défini. Vous pouvez l'utiliser pour définir pour quel attribut (en effet la variable membre) vous voulez appeler un getter ou un setter.

// LableTag is a class defined globally and GetAttribute() is a member 
//template function 
int i = Vox[1][2][3]->GetAttribute<LableTag>(); 

Cependant, je ne l'ai pas vu utilisé pour définir des getters/setters. Habituellement, si vous voulez "obtenir quelque chose", vous écrivez simplement une fonction membre concrète GetSomething();