web-dev-qa-db-fra.com

Renvoie un tableau de chaînes en fonction C++

Je suis nouveau en C++ . Pour un projet d’école, je dois créer une fonction capable de renvoyer un tableau de chaînes.

Actuellement, j'ai ceci dans mon en-tête:

Config.h

string[] getVehicles(void);

Config.cpp

string[] Config::getVehicles(){
string test[5];
test[0] = "test0";
test[1] = "test1";
test[2] = "test2";
test[3] = "test3";
test[4] = "test4";

return test;}

Évidemment, cela ne fonctionne pas, mais c’est l’idée de ce que j’essaie de faire .. En Java, c’est la façon de le faire. J'ai essayé de chercher mon problème sur Google mais je n'ai trouvé aucune réponse claire pour être honnête.

15
sn0ep

Dans ce cas, il vaut peut-être mieux utiliser un vecteur, mais ce n’est pas une réponse correcte à la question. La raison pour laquelle cela ne fonctionne pas, c'est que la variable test existe simplement dans l'étendue de votre fonction . Vous devez donc gérer vous-même la mémoire. Voici un exemple:

string* getNames() {
 string* names = new string[3];
 names[0] = "Simon";
 names[1] = "Peter";
 names[2] = "Dave"; 

 return names;
}

Dans ce cas, vous retournez un pointeur de la position dans le tas. Toute la mémoire du tas doit être libérée manuellement. Donc, votre travail consiste maintenant à effacer la mémoire, si vous n'en avez plus besoin:

delete[] names;
25
GreenPepper

En C++, vous n'utilisez pas un tableau, mais une instance std::vector. Les tableaux en C++ doivent avoir une longueur fixe au moment de la compilation, tandis que les instances std::vector peuvent changer de longueur au moment de l'exécution.

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test(5);
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    return test;
}

std::vector peut également croître de manière dynamique. Ainsi, dans un programme C++, vous trouverez plus souvent quelque chose comme:

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test; // Empty on creation
    test.Push_back("test0"); // Adds an element
    test.Push_back("test1");
    test.Push_back("test2");
    test.Push_back("test3");
    test.Push_back("test4");
    return test;
}

L'affectation dynamique d'un tableau de std::string est techniquement possible, mais c'est une idée terrible en C++ (par exemple, C++ ne fournit pas le garbage collector dont dispose Java).

Si vous voulez programmer en C++, alors prenez un bon livre en C++ et lisez-le en entier ... l'écriture de code Java en C++ est une recette pour un désastre, car les langages, malgré la similitude des accolades superficielles, sont très très différent à bien des égards fondamentaux.

12
6502

Utilisez un std::vector<std::string> . Il est beaucoup plus facile de gérer que des tableaux de style C-.

#include <string>
#include <vector>

...

std::vector<std::string> Config::getVehicles()
{
  std::vector<std::string> data;
  data.Push_back("hello");
  ...
  return data;
}

Découvrez les autres conteneurs de la bibliothèque standard, ils constituent presque toujours un meilleur choix que les tableaux ordinaires en C++.

Si votre méthode getVehicles ne modifie pas l'état de l'objet Config, envisagez de le rendre const:

std::vector<std::string> Config::getVehicles() const { ... }
6
Mat

Essaye ça

#include <iostream>
#include <string>

using namespace std;

string * essai()
    {
    string * test = new string[6];
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    cout<<"test et *test\t"<<&test<<' '<<*(&test)<<'\n';
    return test;
    }

main()
    {
    string * toto;
    cout<<"toto et *toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    toto = essai();
    cout<<"**toto\t"<<*(*(&toto))<<'\n';
    cout<<"toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    for(int i=0; i<6 ; i++)
        {
        cout<<toto[i]<<' '<<&toto[i]<<'\n';
        }
    }

Par exemple, sur mon ordinateur, le résultat est

toto et *toto   0x7ffe3a3a31b0 0x55dec837ae20
test et *test   0x7ffe3a3a3178 0x55dec9ddd038
**toto  test0
toto    0x7ffe3a3a31b0 0x55dec9ddd038
test0 0x55dec9ddd038
test1 0x55dec9ddd058
test2 0x55dec9ddd078
test3 0x55dec9ddd098
test4 0x55dec9ddd0b8
 0x55dec9ddd0d8

Obtenir des adresses et des contenus d'adresses peut vous aider à comprendre qu'un tableau en c ++ est vraiment rudimentaire: il n'offre aucune méthode et vous pouvez accéder à un index sans allouer de mémoire (la valeur 6 dans la boucle) . Votre premier exemple montre une allocation directe d'un tableau local (test), vous ne pouvez donc pas le retourner (le tableau local meurt), dans cet exemple, la variable locale meurt également, mais il existe toujours une variable qui accède à cette partie de la mémoire allouée, la fonction , puis la variable qui reçoit le résultat de la fonction. Par conséquent, la variable test est morte après l'appel de la fonction, mais la mémoire est toujours allouée. Cordialement.

0
Alain Isbaquipof