1. 从main返回
所有返回类型非void的函数必须有返回值,main函数是唯一的例外:如果main终止但没有return,编译器会隐式地插入返回0的语句。main 的返回值被视为状态指示符。0表示成功,绝大多数其他值都表示失败,非0返回值含义和机器相关,为了使返回值和机器无关,可以使用 EXIT_FAILURE 和 EXIT_SUCCESS, 定义在头文件 <cstdlib> 中:
#include <cstdlib> int main() { if (some_failure) return EXIT_FAILURE; else return EXIT_SUCCESS; }
不过我不知道这样写有什么好处,main的返回值要怎么处理。
2. 返回非引用类型
在函数调用的时间点会创建一个临时对象,函数的返回值被用来初始化这个临时对象。当编译器需要一个地方存储计算表达式得到的结果时,就会创建一个未命名的临时对象。
就像实参初始化形参一样,函数的返回值用来初始化临时对象。如果返回类型非引用,返回值可以是一个局部对象或表达式的结果, 会在调用函数的地方复制到临时对象。
例子,如果counter > 1, 返回word的复数形式,return将string 复制给调用方:
// return plural version of word if ctr isn't 1 string make_plural(size_t ctr, const string &word, const string &ending) { return (ctr == 1) ? word : word + ending; }
3. 返回引用
如果返回引用,那么返回值不会被复制而是返回对象自身:
// find longer of two strings const string &shorterString(const string &s1, const string &s2) { return s1.size() < s2.size() ? s1 : s2; }
4. 返回的引用为左值
char &get_val(string &str, string::size_type ix) { return str[ix]; } int main() { string s("a value"); cout << s << endl; // prints a value get_val(s, 0) = 'A'; // changes s[0] to A cout << s << endl; // prints A value return 0; }
如果不希望返回值被修改,那么函数返回类型应该改为 const char& getval(...)
5. 不要返回局部对象的引用或指针
// Disaster: Function returns a reference to a local object const string &manip(const string& s) { string ret = s; // transform ret in some way return ret; // Wrong: Returning reference to a local object! }
会出现运行时错误。因为函数退出时,局部对象会被释放,如果返回指针,指针会指向不存在的对象。
C++ primer 7.3