为什么从函数返回向量是可以的?
请考虑这个代码,我已经看了几次这种types的代码, words
是本地向量,怎么可能从函数返回。 我们可以保证它不会死?
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; }
我们可以保证它不会死?
只要没有返回参考,这样做是完全正确的。 words
将被移到接收结果的variables。
局部variables将超出范围。 它被移动(或复制)之后。
Pre C ++ 11:
该函数不会返回局部variables,而是返回它的副本。 但是,编译器可能会执行优化,而不会进行实际的复制操作。
看到这个问题和答案的进一步细节
C ++ 11:
该函数将移动该值,看到这个答案进一步的细节
我认为你指的是在C(和C + +)从一个函数返回一个数组的问题是不允许的(或至less不会按预期工作) – 这是因为数组返回将(如果你写在简单的forms)返回一个指向堆栈上的实际数组的指针,然后当函数返回时,该指针立即被移除。
但在这种情况下,它的工作原理,因为std::vector
是一个类,类,像结构,可以(和将)被复制到调用者上下文。 [实际上,大多数编译器会使用所谓的“返回值优化”来优化这种特定types的副本,特别是为了避免在从函数返回时拷贝大对象,而这是一个优化,从程序员的angular度来看,它会performance得好像为该对象调用了赋值构造函数一样]
只要你不返回一个指针或引用返回的函数内的东西,你没事。
为了理解这个行为,你可以运行下面的代码:
#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; }
输出如下:
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()
这实际上是一个devise失败,你不应该使用任何不是一个简单的任何东西,而不是一个返回值。 理想的解决scheme应该通过一个返回参数来实现,这个参数是通过一个关于reference / ptr的决定和正确使用一个“const \'y \'s”来描述的。
最重要的是,你应该认识到,在C和C ++数组上的标签实际上是一个指针,它的订阅实际上是一个偏移量或一个加法符号。
所以标签或ptr array_ptr ===数组标签因此返回foo [offset]实际上是指内存中的返回元素ptr位置foo +返回types的偏移量。