Arg*_*art 4 c++ reference lvalue
人们可以经常读到,你不能将正常的左值引用绑定到临时对象.因为当他们不想涉及复制时,可以经常看到A类的方法将const A&作为参数.但是,这种结构是完全合法的:
double& d = 3 + 4;
Run Code Online (Sandbox Code Playgroud)
因为它不会将临时对象3 + 4绑定到引用d,而是使用对象3 + 4初始化引用.正如标准所说,只有当值不是类型或引用(或继承)时,引用才不会使用从临时对象获得的对象使用转换或sth(即另一个临时对象)初始化.在这种情况下你可以看到:
int i = 2;
double & d = i;
Run Code Online (Sandbox Code Playgroud)
这不合法,因为我不是double类型,也不是继承它.然而,这意味着,临时工可以绑定到引用 - 但它是否真的具有约束力?是不是使用临时对象作为参数的复制构造函数创建新对象?
因此,正如我认为的那样,使用const A¶m代替A&的方法并不是第二种情况下这种方法不能作为A类参数临时对象(因为它会),但因为它涉及到复制构造函数(就像参数类型为A一样).我对吗?
首先,正如其他人所说,double&d = 3 + 4; 是不合法的C++; 如果您的编译器接受它,并声称正在编译C++,那么它在编译器中是一个错误.(请注意,大多数C++编译器都没有声称编译C++,除非你给它们特殊的选项,-std=c++98例如g ++).
其次,这条规则的动机来自经验.请考虑以下示例:
void
incr( int& i )
{
++ i;
}
unsigned x = 2;
incr( x ); // Implicit conversion of unsigned to int
// creates a temporary.
std::cout << x << std::endl;
// and x is still equal 2 here.
Run Code Online (Sandbox Code Playgroud)
最初的引用实现没有这个限制; 你可以用临时的方式初始化任何引用.实际经验表明这很容易出错,因此引入了需要引用const的限制.(大约在1988年或1989年左右,所以今天没有理由让编译器不执行它.)
另请注意,人们经常听到将临时绑定到const引用会延长临时生命周期.这是非常误导的:使用临时初始化引用会延长临时的生命周期(有一些例外),但如果使用此引用初始化其他引用,则生命周期不会扩展,即使临时也绑定到这些引用.
如果你担心函数参数列表中的const &vs 的含义和目的&,我担心你正在咆哮错误的树,因为它与临时对象没什么关系.
void method( Object x );
Run Code Online (Sandbox Code Playgroud)
这会Object从实际参数中复制构造一个.x当函数终止时,对函数内所做的任何更改都将丢失,函数的参数不会更改.
但是你不想支付复制结构的费用.
void method( Object & x );
Run Code Online (Sandbox Code Playgroud)
这并没有拷贝构造Object从实际的说法,但X 指的说法,即做任何更改x的函数中真的做参数本身.
但是你不希望方法的调用者想知道他们的参数会发生什么.
void method( const Object & x );
Run Code Online (Sandbox Code Playgroud)
这并没有拷贝构造Object从实际的参数,而x不能在函数内改变.
您不需要为复制构造函数付费,并且您向调用者明确说明他的参数不会被篡改.
你不能将临时对象作为参数传递给第二个变体(参见unapersson的答案),因为没有可变对象可以引用,但是因为该函数大声预示它将修改参数(因为它被声明为非const)参考),传递一个临时的参数是无意义的.
| 归档时间: |
|
| 查看次数: |
2269 次 |
| 最近记录: |