Dlaczego warto zwracać wektor z funkcji?
Proszę wziąć pod uwagę ten kod. Widziałem ten typ kodu kilka razy. words
jest wektorem lokalnym. Jak jest możliwe zwrócenie go z funkcji? Możemy zagwarantować, że nie umrze?
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;
}
5 answers
Czy możemy zagwarantować, że nie umrze?
Tak długo, jak nie ma odniesienia zwrócone, to jest całkowicie w porządku, aby to zrobić. words
zostanie przeniesiony do zmiennej otrzymującej wynik.
Zmienna lokalna wyjdzie poza zakres. po jego przeniesieniu (lub skopiowaniu).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 08:22:40
Pre C++11:
Funkcja nie zwróci zmiennej lokalnej, lecz jej kopię. Kompilator może jednak przeprowadzić optymalizację, w której nie zostanie wykonana żadna rzeczywista akcja kopiowania.
Zobacz to pytanie i ODPOWIEDŹ aby uzyskać więcej szczegółów
C++11:
Funkcja przeniesie wartość, zobacz ta ODPOWIEDŹ aby uzyskać więcej informacji
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26
Myślę, że odnosisz się do problemu w C (i c++), że zwracanie tablicy z funkcji jest niedozwolone (lub przynajmniej nie będzie działać zgodnie z oczekiwaniami) - dzieje się tak dlatego, że zwrócenie tablicy (jeśli napiszesz ją w prostej formie) zwróci wskaźnik do rzeczywistej tablicy na stosie, która jest natychmiast usuwana po powrocie funkcji.
Ale w tym przypadku to działa, ponieważ std::vector
jest klasą, A klasy, podobnie jak struktury, mogą (i będą) być kopiowane do kontekstu wywołującego. [Właściwie, większość kompilatorów optymalizuje ten konkretny typ kopii za pomocą czegoś o nazwie "Return Value Optimization", specjalnie wprowadzonego, aby uniknąć kopiowania dużych obiektów, gdy są one zwracane z funkcji, ale jest to optymalizacja, a z punktu widzenia programistów, będzie to zachowywać się tak, jakby konstruktor przypisania został wywołany dla obiektu]
Dopóki nie zwrócisz wskaźnika lub odniesienia do czegoś, co znajduje się w zwracanej funkcji, jesteś w porządku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 08:28:45
Aby dobrze zrozumieć zachowanie, możesz uruchomić ten kod:
#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;
}
Wyjście jest następujące:
run my_function()
run constructor MyClass::MyClass()
my_function is going to return a...
run constructor MyClass::MyClass()
run my_function()
run constructor MyClass::MyClass()
my_function is going to return a...
run assignation MyClass::operator=(const MyClass&)
run destructor MyClass::~MyClass()
run destructor MyClass::~MyClass()
run destructor MyClass::~MyClass()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 15:53:08
Jest to w rzeczywistości błąd w projektowaniu, nie powinieneś używać wartości zwrotnej do niczego, a nie prymitywnej do niczego, co nie jest stosunkowo trywialne. Idealne rozwiązanie powinno być zaimplementowane poprzez parametr powrotu z decyzją o referencji / ptr i właściwym użyciu "const\' y\ 'ness" jako deskryptora.
Poza tym powinieneś zdać sobie sprawę, że etykieta na tablicy w C i C++ jest efektywnie wskaźnikiem, a jej subskrypcja jest efektywnie przesunięciem lub dodatkiem symbol.
Tak więc etykieta lub ptr array_ptr = = = Etykieta tablicy zwracająca foo [offset] tak naprawdę mówi element return w pamięci ptr location foo + offset typu return type.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-15 01:15:07