2010-09-24 10 views
1

Je dois retourner 3 valeurs. X, Y, Z. J'ai essayé quelque chose comme ça, mais ça ne marche pas, quelqu'un peut-il m'aider un peu? J'ai regardé ici: Return a float array in C++ et j'ai essayé de faire la même chose, sauf avec un tableau de 1 dimension pour revenir.Retour tableau de la classe

class Calculate 
{ 
float myArray[3][4], originalArray[3][4], tempNumbers[4]; 
float result[3]; // Only works when result is 2 dimensional array, but I need 1 dimension. 

public: 
Calculate(float x1, float y1, float z1, float r1, 
    float x2, float y2, float z2, float r2, 
    float x3, float y3, float z3, float r3) 
{ 
    myArray[0][0] = x1; 
    myArray[0][1] = y1; 
    myArray[0][2] = z1; 
    myArray[0][3] = r1; 

    myArray[1][0] = x2; 
    myArray[1][1] = y2; 
    myArray[1][2] = z2; 
    myArray[1][3] = r2; 

    myArray[2][0] = x3; 
    myArray[2][1] = y3; 
    myArray[2][2] = z3; 
    myArray[2][3] = r3; 

    result[0] = 1; 
    result[1] = 2; 
    result[2] = 3; 
} 

float* operator[](int i) 
{ 
    return result[i]; //Value type does not match the function type 
} 

const float* operator[](int i) const 
{ 
    return result[i]; //Value type does not match the function type 
} 
}; 
+0

Devrait probablement être '& result [i]'. – Archimedix

Répondre

4

Au lieu de renvoyer un pointeur, il est généralement préférable d'accepter un pointeur et d'y écrire les résultats. De cette façon, quelqu'un peut allouer un tableau régulier sur la pile et l'initialiser par votre Calculer.

Quelque chose comme:

class Calculate 
{ 
float myArray[3][4], originalArray[3][4], tempNumbers[4]; 

public: 
Calculate(float x1, float y1, float z1, float r1, 
    float x2, float y2, float z2, float r2, 
    float x3, float y3, float z3, float r3, float *result) 
{ 
    myArray[0][0] = x1; 
    myArray[0][1] = y1; 
    myArray[0][2] = z1; 
    myArray[0][3] = r1; 

    myArray[1][0] = x2; 
    myArray[1][1] = y2; 
    myArray[1][2] = z2; 
    myArray[1][3] = r2; 

    myArray[2][0] = x3; 
    myArray[2][1] = y3; 
    myArray[2][2] = z3; 
    myArray[2][3] = r3; 

    result[0] = 1; 
    result[1] = 2; 
    result[2] = 3; 
} 
}; 

D'autres réglages que vous pouvez faire - séparer le constructeur du calcul, étant donné que les constructeurs sont plus pour l'initialisation; et passer des tableaux pour le contrôle de la mémoire plus sûre:

class Calculate 
{ 
    float myArray[3][4], originalArray[3][4], tempNumbers[4]; 

public: 
    Calculate(const float initArray[3][4]) 
    { 
     for (int i = 0; i < 3; i++) 
      for (int j = 0; j < 4; j++) 
       myArray[i][j] = initArray[i][j]; 
    } 

    void DoCalculation(float result[3]) const 
    { 
     result[0] = 1; 
     result[1] = 2; 
     result[2] = 3; 
    } 
}; 

int main() 
{ 
    float myArray[3][4] = 
    { 
     { 0, 1, 2, 3 }, 
     { 4, 5, 6, 7 }, 
     { 8, 9, 0, 1 } 
    }; 
    float result[3]; 
    Calculate calc(myArray); 
    calc.DoCalculation(result); 
    return 0; 
} 
+0

Merci, a bien fonctionné, encore mieux parce qu'il prend moins de code. – sed

+1

Notez que les pointeurs de passage ne sont généralement pas considérés comme une meilleure pratique en C++, mais que, par ailleurs, les pointeurs ne retournent pas aux membres internes d'une classe. – jkerian

+0

@jkerian, Yup; c'est pourquoi je préfère l'approche de @ Thomas Matthews. – strager

2

result[i] est un flotteur, pas un * flotteur, de sorte que vous pouvez faire

const float operator[](int i) const 
{ 
    return result[i]; 
} 

Mais je pense que vous ne voulez retourner une référence pour obtenir le bon sémantique, donc vous voulez

const float& operator[](int i) const 
{ 
    return result[i]; 
} 

float& operator[](int i) 
{ 
    return result[i]; 
} 

Droit? (Je pense que c'est OK - il compile mais cela fait un moment que je l'ai fait ...)

0

Dans le code, où vous obtenez une erreur, vous n'essayez pas de retourner un pointeur. Vous essayez de renvoyer un seul flottant à l'index donné.

Calculate c; 
float first = c[0]; 
float second = c[1]; 
float third = c[2]; 

Si vous vouliez retourner un pointeur vers le tableau results, alors vous devez retourner le tableau, par exemple

float* GetResult() { return result; } 

Il n'a probablement pas beaucoup que vous allez continuer parce que la l'effet de fin est à peu près la même chose. Si vous surchargez operator[], vous aurez plus de contrôle, car vous pouvez vérifier les accès hors-limite.

2

Une autre alternative est de faire la result comme une structure séparée et soit le retourner comme une valeur ou de le transmettre par référence:

struct Result_Type 
{ 
    double values[3]; 
// Alternatively: 
// double x; 
// double y; 
// double z; 
}; 

// Returning a result 
const Result_Type calculate_result_1(/* yada yada yada */) 
{ 
    Result_type new_result; 
    new_result.value[0] = 0; 
    new_result.value[1] = 0; 
    new_result.value[2] = 0; 
    return result; // Return the result as a object 
} 

// Or passing a result to be modified 
void clear_result(Result_Type & any_result) // <-- Note pass by reference 
{ 
    any_result.value[0] = 0; 
    any_result.value[1] = 0; 
    any_result.value[2] = 0; 
    return; 
} 

Vous trouverez peut-être que c'est une conception préférée puisque vous pouvez passer autour des résultats , modifiez la structure Result_Type pour effectuer des opérations avec un autre résultat vecteurs (terme mathématique). La matrice peut également être considérée comme une composition de vecteurs de résultats.

Cela peut faciliter la lecture du code.

+0

+1 sauf pour une chose: je ne mettrais pas un tableau dans la structure, mais trois valeurs séparées (dont chacune a sa propre signification, comme x, y et z par exemple). – rubenvb

0

Certaines réponses ont indiqué l'utilisation de pointeurs. Le problème est de savoir qui alloue ce pointeur et qui le libère. Aussi, il faut vérifier si le pointeur entrant est NULL et ainsi de suite. Au lieu de cela, je suggérerais la déclaration suivante du constructeur.

Calculate(float x1, float y1, float z1, float r1, 
    float x2, float y2, float z2, float r2, 
    float x3, float y3, float z3, float r3, float (&r)[3]) 

Ceci est beaucoup plus sûr car les références ne peuvent pas être NULL.