112 votes

Pourquoi il est OK pour revenir vecteur de fonction?

Veuillez considérer ce code, j'ai vu ce type de code plusieurs fois, words est locale du vecteur, comment il est possible de retour de la fonction. Pouvons-nous garantir qu'il ne mourra pas?

 std::vector<std::string> read_file(const std::string& path)
 {
    std::ifstream file("E:\\names.txt");

    if (!file.is_open())
    {
        std::cerr << "Unable to open file" << "\n";
        std::exit(-1);
    }

    std::vector<string> words;//this vector will be returned 
    std::string token;

    while (std::getline(file, token, ','))
    {
        words.push_back(token);
    }

    return words;
}

107voto

Tim Meyer Points 5480

"Vieux" C++:

La fonction ne sera pas de retour la variable locale, mais plutôt une copie de celui-ci. Votre compilateur peut cependant effectuer une optimisation lorsque aucune action de copie est faite.

Voir cette question & réponse pour plus de détails

C++11:

La fonction de déplacement de la valeur, de voir cette réponse pour plus de détails

69voto

πάντα ῥεῖ Points 15683

Pouvons-nous garantir qu'il ne mourra pas?

Tant de référence n'est pas retourné, il est parfaitement bien de le faire. words sera déplacé à la variable recevant le résultat.

La variable locale sera hors de portée. après, il a été déplacé (ou copié).

26voto

Mats Petersson Points 70074

Je pense que vous faites référence au problème en C (et C++) que de retourner un tableau à partir d'une fonction n'est pas autorisée (ou au moins de ne pas fonctionner comme prévu) - c'est parce que le tableau de retour (si vous l'écrivez dans le formulaire simple) retourne un pointeur sur le tableau réel sur la pile, qui est ensuite retiré rapidement lorsque la fonction retourne.

Mais dans ce cas, il fonctionne, parce que l' std::vector est une classe et dans les classes, comme les structures, peuvent (et vont) être copié dans le contexte des appelants. [En fait, la plupart des compilateurs optimiser ce type particulier de copie à l'aide de quelque chose qui s'appelle "Retour Optimisation de la Valeur", spécifiquement mis en place pour éviter la copie de gros objets quand ils sont retournés à partir d'une fonction, mais c'est une optimisation, et de programmateurs de point de vue, il va se comporter comme si l'affectation constructeur est appelé pour l'objet]

Tant que vous n'avez pas retourner un pointeur ou une référence à quelque chose qui est de la fonction de retour, vous êtes beaux.

13voto

Caduchon Points 465

Pour bien comprendre le comportement, vous pouvez exécuter ce code :

#include <iostream>
class MyClass
{
  public:
    MyClass() { std::cout << "run constructor MyClass::MyClass()" << std::endl; }
    ~MyClass() { std::cout << "run destructor MyClass::~MyClass()" << std::endl; }
    MyClass(const MyClass& x) { std::cout << "run copy constructor MyClass::MyClass(const MyClass&)" << std::endl; }
    MyClass& operator = (const MyClass& x) { std::cout << "run assignation MyClass::operator=(const MyClass&)" << std::endl; }
};

MyClass my_function()
{
  std::cout << "run my_function()" << std::endl;
  MyClass a;
  std::cout << "my_function is going to return a..." << std::endl;
  return a;
}

int main(int argc, char** argv)
{
  MyClass b = my_function();

  MyClass c;
  c = my_function();

  return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X