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

时间:2012-11-07 18:39:22

标签: c++ class

访问属于方法类的成员数据/函数的正确方法是什么?似乎有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
        }
};

他们似乎都尽我所能。它们是等价的吗?除了样式/一致性之外,是否有理由使用其中一个?

8 个答案:

答案 0 :(得分:3)

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

“方法2”可用于消除局部变量和类成员之间的歧义。

“方法3”可用于消除类层次结构不同位置中具有相同名称的字段之间的歧义。

答案 1 :(得分: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
}

答案 2 :(得分:1)

  • 方法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
}

答案 3 :(得分:1)

对于对象内部的代码,它通常没有区别,所以通常使用variable = value;并且完成它是最干净的。

有时候在模板中,你可能会遇到这样一种情况:只使用变量名本身是不明确的,this->variable消除了这种歧义 - 但这很少见,我肯定会不< / em>定期使用this->everything只是因为它可能在很长一段时间内有用。

答案 4 :(得分:0)

指针通常用于在类的重载运算符中进行比较。其中一个用途是,如果函数中传递的参数与对象本身相同,例如:

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->的使用不明确,除非您正在检查值。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

并添加上述答案: 一些代码样式喜欢使用固定前缀(如_m)来标识成员变量。使用“方法2”是在代码中实现这种清晰度的另一种(并且非常好的方式)。

首选this->value超过value也有点像使用std::cin代替cin using namespace std

答案 7 :(得分:-1)

使用方法1

variable = value;

让您经常购买新键盘!

(说过我应该停止将咖啡放在我的上面!)