从对象本身访问成员或成员范围

Accessing members from an object itself with either THIS or member scope

本文关键字:成员 范围 访问 对象      更新时间:2023-10-16

访问该类别类的成员数据/功能的正确方法是什么?似乎有3个含义:

class test{
    private:
        int variable;
    public:
        void setVariable(int value) {
            variable = value;        // method 1, using the variable name directly
            this->variable = value;  // method 2, via pointer dereference of 'this'
            test::variable = value;  // method 3, via scope operator
        }
};

他们似乎都在工作。他们等效吗?除了样式/一致性外,是否有理由使用另一个?

除了您提到的样式和一致性,有时您还必须使用特定的语法来消除歧义。

"方法2"可以用来消除本地变量和类成员之间的歧义。

"方法3"可以用来在类层次结构的不同位置的同名字段之间消除歧义。

通常,它无关紧要,因此更简单的选项member = value;是首选。在某些情况下,局部变量可能会有歧义,您可以在那里符合this->前缀的资格,但是更好的方法是完全避免歧义。

然而,在某些角案件中确实很重要。处理虚拟函数时,使用合格的名称(type::member禁用运行时调度并确保type级别的最终超级层被调用:

struct base {
   virtual int f() { return 1; }
};
struct derived : base {
   virtual int f() { return 2; }
   void g() {
      std::cout << f() << "n";
      std::cout << derived::f() << "n";
   }
};
struct mostderived : derived {
   virtual int f() { return 3; }
};
int main() {
   mostderived d;
   d.g();            // 3 2
}

处理模板类和继承时,查找分为两个阶段。在第一阶段,必须解决非依赖性名称。不合格的名称是一个非依赖性名称,因此在某些情况下,您需要使用this->type::的资格,并且上述区别仍然适用。额外的资格用于使名称取决于

template <typename T>
struct derived : T {
   void g() {
      // std::cout << f() << "n";    // Error, cannot resolve f() [*]
      this->f();                      // Ok, pick final overrider at runtime 
      derived::f();                   // Ok, pick overrider here: base::f()
   }
};
struct base {
   virtual int f() { return 1; }
};
struct mostderived : derived<base> {
   virtual int f() { return 3; }
};
int main() {
   mostderived d;
   d.g();                             // 3, 1
}

对于对象内的代码,通常没有区别,因此通常只使用variable = value;并使用它是最干净的。

有时在模板中,您可能会遇到一个仅使用变量名称的情况,而this->variable消除了这种歧义 - 但这很少足够this->everything定期仅仅是因为它可能会偶尔有用。

  • 方法1:这是完成的常见方式。
  • 方法2 :这是做到这一点的最佳和最一致性的方法。很清楚阅读和理解正在发生的事情。
  • 方法3:我从未在现实世界代码中见过。

作为侧面注释:使用方法1 时,如果与函数参数发生命名冲突,并且成员变量将在成员变量上使用函数参数。

如果我们有:

void setVariable(int variable) {
    variable = variable;        // method 1, this does not change the member variable.
    this->variable = variable;  // method 2, via pointer dereference of 'this'
    test::variable = variable;  // method 3, via scope operator
}

指针通常用于类的超载运算符。它的用途之一可以是,如果函数中传递的参数与对象本身相同,例如:

class CDummy {
  public:
    int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
  if (&param == this) return true;
  else return false;
} 

也用于将指针返回到对象本身

ClassEx ClassEx::Func(//params)
{
    //code
    return *this;
}

按照正常的比较,value而不是this->value的使用效率更高,除非您检查值,否则this->的使用是模棱两可的。

性能没有差异。::用于避免歧义,例如,当您具有具有相同名称的本地变量时,或在派生类中声明字段相同名称的字段。支持->是因为this的类型是指向对象的指针,因此编译器必须接受this->something,并且也可以用于避免歧义或只是让代码更加清晰。

,并添加到上述答案中:某些代码样式喜欢使用固定前缀(例如_m)识别成员变量。使用"方法2"是在代码中实现这一清晰度的另一种(并且更好的方法)。

优于this->value而不是value,也有点像使用std::cin代替cinusing namespace std

使用方法1

variable = value;

节省您如此频繁购买新键盘!

(说我应该停止在我的咖啡上维咖啡!)