标签:must 地址 iostream ++ tor typename access stream bsp
本文翻译自:https://docs.microsoft.com/en-us/cpp/cpp/reference-type-function-arguments?view=vs-2019
通常情况下相对于传递较大的对象,传递引用给函数更高效。传递引用给函数允许编译器传递对象的地址给函数的同时,保留用于直接访问该对象的syntax(应该指的是对象名称?)。This allows the compiler to pass the address of the object while maintaining the syntax that would have been used to access the object.
// reference_type_function_arguments.cpp #include <iostream> struct Date { short Month; short Day; short Year; }; // Create a date of the form DDDYYYY (day of year, year) // from a Date. long DateOfYear( Date& date ) { static int cDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; long dateOfYear = 0; // Add in days for months already elapsed. for ( int i = 0; i < date.Month - 1; ++i ) dateOfYear += cDaysInMonth[i]; // Add in days for this month. dateOfYear += date.Day; // Check for leap year. if ( date.Month > 2 && (( date.Year % 100 != 0 || date.Year % 400 == 0 ) && date.Year % 4 == 0 )) dateOfYear++; // Add in year. dateOfYear *= 10000; dateOfYear += date.Year; return dateOfYear; } int main() { Date date{ 8, 27, 2018 }; long dateOfYear = DateOfYear(date); std::cout << dateOfYear << std::endl; }
上述例子展示了通过引用传递的结构体对象的成员是通过成员选择运算符(. member-selection operator)访问的,而不是指针的成员选择操作符->。
虽然通过引用传递的参数遵循非指针类型的语法,引用保留了指针的一个重要特性:除非被声明为const,它们都是可修改的。上面例子中并没有修改传入参数,因此应修改为:
long DateOfYear( const Date& date );
这样就保证了函数DateOfYear不会修改传入的参数。
Any function prototyped as taking a reference type can accept an object of the same type in its place because there is a standard conversion from typename to typename&.任何参数是引用类型的函数可以直接接受一个同类型的对象,因为存在从类型到类型引用的标准转换(也就是说:如果一个函数的参数是引用,你可以将一个对象直接传递给它)。
函数可以被声明为返回一个引用类型,有两个原因这样做:
与通过引用传递大的对象给函数会更高效类似,从函数中返回大对象的引用也会更高效。从函数中返回对象的引用消除了在函数返回前将对象拷贝到一个临时内存位置的必要性。
当函数被认为是左值是返回引用类型的对象也很有帮助。Reference-return types can also be useful when the function must evaluate to an l-value. Most overloaded operators fall into this category, particularly the assignment operator.
例子:
// refType_function_returns.cpp // compile with: /EHsc #include <iostream> using namespace std; class Point { public: // Define "accessor" functions as // reference types. unsigned& x(); unsigned& y(); private: // Note that these are declared at class scope: unsigned obj_x; unsigned obj_y; }; unsigned& Point :: x() { return obj_x; } unsigned& Point :: y() { return obj_y; } int main() { Point ThePoint; // Use x() and y() as l-values. ThePoint.x() = 7; ThePoint.y() = 9; // Use x() and y() as r-values. cout << "x = " << ThePoint.x() << "\n" << "y = " << ThePoint.y() << "\n"; }
输出:
x = 7 y = 9
注意:函数x y被声明为返回引用类型。这两个函数可以出现在赋值操作符=的左右两侧。
注意,在main函数中,ThePoint对象没有被销毁(remains in scope),因此它的成员仍然有且且可以安全的访问。
声明引用类型必须包含初始化器(initializer),除了以下几种情况:
如果你声明一个局部范围内的对象,则当函数离开该返回后对象会被销毁。如果函数返回指向该对象的引用,则使用该引用可能会导致运行时访问冲突(an access violation at runtime)。
// C4172 means Don’t do this!!! Foo& GetFoo() { Foo f; ... return f; } // f is destroyed here
编译器会提示警告:warning C4172: returning address of local variable or temporary
.在简单程序中很容易发现这样的错误,但是随着程序代码的增加这样的错误很难调试,使用时应注意。
todo
标签:must 地址 iostream ++ tor typename access stream bsp
原文地址:https://www.cnblogs.com/zyk1113/p/13282922.html