C ++ derefencing" this"关键词

时间:2017-10-28 02:16:14

标签: c++ this dereference

我目前正在通过学​​习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对象。

4 个答案:

答案 0 :(得分:1)

代码 获取对Sales_data对象的引用。它碰巧是调用其组合函数的同一个对象。

返回对此的引用是为了允许您调用。因此,如果Sales_data具有名为foo()和bar()的其他成员函数,则可以执行此操作

Sales_data sd1
Sales_data sd2;
sd1.combine(sd2).foo().bar();

如果这本书说明了这个'是一个const指针错了。唯一的方法就是这个'如果函数本身被声明为const,则该函数中将是一个const指针。

答案 1 :(得分:1)

thisSales_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引用,例如这个习语。

相关问题