我目前正在通过学习C ++ Primer第5版来学习C ++。我正在本书的一部分深入介绍课程,本书刚刚介绍了这个"这个"关键字。
Sales_data& Sales_data::combine(const Sales_data &rhs){
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
我无法理解此成员函数的返回类型。
函数头声明该函数将返回对Sales_data对象的引用。该书指出 this 的类型是一个const指针。 return语句解析了这将产生Sales_data对象,而不是对Sales_data对象的引用。
我的问题是:上面的代码段不会产生编译时错误,因为函数需要返回对Sales_data的引用,而只是获取Sales_data对象。
答案 0 :(得分:1)
代码 获取对Sales_data对象的引用。它碰巧是调用其组合函数的同一个对象。
返回对此的引用是为了允许您链调用。因此,如果Sales_data具有名为foo()和bar()的其他成员函数,则可以执行此操作
Sales_data sd1
Sales_data sd2;
sd1.combine(sd2).foo().bar();
如果这本书说明了这个'是一个const指针错了。唯一的方法就是这个'如果函数本身被声明为const,则该函数中将是一个const指针。
答案 1 :(得分:1)
this
是Sales_data
类型的非可变指针,而不是const
意义上的int* const
指针。
具体来说,由于你的函数是非常量的,它是Sales_data*
类型的临时(= prvalue),并且由于原始类型的临时值,如指针,不能修改,你不能使{ {1}}指向其他任何内容。
它严格绑定到您所在的对象,并使其成为临时对象,允许将其视为常量指针并保护边界限制,同时允许它在取消引用时返回非const引用。
但是,如果您的函数位于this
,例如:
const
然后Sales_data& Sales_data::foo(const Sales_data &rhs) const;
是this
类型的prvalue;一个指向常量对象的临时指针(因为你有" const" ified该函数内的对象)但不是const Sales_data*
指针(不可修改,因为它是临时的,但不是const
-合格)。因此,const
具有类型*this
,如果在该函数内返回const Sales_data&
,则会出现编译器错误。然后,您必须将函数签名更改为:
*this
答案 2 :(得分:0)
我相信你的困惑来自C ++编译器的一个特性(来自C ++标准)。这两个函数签名意味着不同的东西:
Sales_data& Sales_data::combine(const Sales_data &rhs)
Sales_data Sales_data::combine(const Sales_data &rhs)
第一个意味着该函数将返回Sales_data对象的引用,第二个返回它的副本。编译器非常聪明,可以从函数签名中找出要做的事情,而不是return *this;
语句,这两种情况都是一样的。
答案 3 :(得分:0)
不了解C ++引用是初学者C ++程序员常见的陷阱。引用是伪装的常量指针,自动解引用。 是一个指针,但用作一个值,每次使用 创建它之后,*会在标识符之前无形地添加*。您总是通过为其指定内容来创建引用,并且当您执行此操作时,& 将无形地添加到正在分配的实体中,并获取其地址。因此,分配 * this 实际上意味着& * this ,其中&否定*,参考只是得到指针这个的值。
在Sales_data类的方法中使用时,此是指向 Sales_data 类型对象的指针。 这个方法的返回类型是一个引用,正如我已经解释过的那样,它本质上也是一个指向同一类型的指针,但是使用了不同的语法。返回 * this 只是在实际执行 nothing 时在指针的语法和引用的语法之间进行转换。
基本上,这两种情况生成完全相同的代码但看起来不同。
Sales_data& Sales_data::combine(const Sales_data &rhs){
// ...
return *this;
}
// ...
{
Sales_data a, b, c, d;
a.combine(b).combine(c).combine(d);
}
Sales_data* Sales_data::combine(const Sales_data &rhs){
// ...
return this;
}
// ...
{
Sales_data a, b, c, d;
(*(*a.combine(b)).combine(c)).combine(d);
// Or, also exactly the same code:
a.combine(b)->combine(c)->combine(d);
}
在阅读一段孤立的代码时,无法区分引用和值是许多C ++“特性”中的一个,这些特性使其成为一种专为拍摄你的腿而设计的语言应得的名声。 为了保持你的理智,你应该更喜欢const引用,并且只对少数情况使用非const引用,例如这个习语。