C++ 我应该在什么时候明确使用'this'指针?

C++ 我应该在什么时候明确使用'this'指针?,c++,this,C++,This,我应该在什么时候以一种方法显式地编写this->member 类?如果在与现有成员同名的方法中声明局部变量,则必须使用此->变量来访问类成员,而不是局部变量 #include <iostream> using namespace std; class A { public: int a; void f() { a = 4; int a = 5; cout <<

我应该在什么时候以一种方法显式地编写
this->member

类?

如果在与现有成员同名的方法中声明局部变量,则必须使用此->变量来访问类成员,而不是局部变量

#include <iostream>
using namespace std;
class A
{
    public:
        int a;

        void f() {
            a = 4;
            int a = 5;
            cout << a << endl;
            cout << this->a << endl;
        }
};

int main()
{
    A a;
    a.f();
}
#包括
使用名称空间std;
甲级
{
公众:
INTA;
void f(){
a=4;
INTA=5;

cout您需要使用
this
来消除参数/局部变量和成员变量之间的歧义

class Foo
{
protected:
  int myX;

public:
  Foo(int myX)
  {
    this->myX = myX; 
  }
};

如果在两个可能的名称空间中有同名的符号,则只需使用此->即可。例如:

class A {
public:
   void setMyVar(int);
   void doStuff();

private:
   int myVar;
}

void A::setMyVar(int myVar)
{
  this->myVar = myVar;  // <- Interesting point in the code
}

void A::doStuff()
{
  int myVar = ::calculateSomething();
  this->myVar = myVar; // <- Interesting point in the code
}
A类{
公众:
void setMyVar(int);
void doStuff();
私人:
int-myVar;
}
void A::setMyVar(int-myVar)
{

这->myVar=myVar;///myVar=myVar;//通常,您不必这样做,
这->
是隐含的

有时会出现名称歧义,可用于消除类成员和局部变量的歧义。然而,这里有一个完全不同的情况,明确要求
this->

考虑以下代码:

template<class T>
struct A {
   int i;
};

template<class T>
struct B : A<T> {

    int foo() {
        return this->i;
    }

};

int main() {
    B<int> b;
    b.foo();
}
  • 其中成员变量将被隐藏 局部变量
  • 如果你只是想 清楚地表明你 正在调用实例方法/变量

  • 一些编码标准使用方法(2),因为他们声称这使代码更易于阅读。

    例如:
    假设MyClass有一个名为“count”的成员变量

    void MyClass::DoSomeStuff(void)
    {
       int count = 0;
    
       .....
       count++;
       this->count = count;
    }
    

    您可能需要显式地使用
    这个
    指针有几个原因

    • 当您希望将对象的引用传递给某个函数时
    • 当存在与成员对象同名的本地声明对象时
    • 当您尝试访问的成员时
    • 有些人更喜欢使用符号来直观地消除代码中成员访问的歧义
    其他用法(正如我在阅读摘要和一半问题时所想的那样……),忽略其他答案中的(错误的)命名歧义消除,是如果要强制转换当前对象,将其绑定到函数对象中,或将其与指向成员的指针一起使用

    铸造
    void Foo::bar(){
    杂项非库存物品();
    const Foo*const_this=this;
    const_this->bar();//调用const version
    dynamic_cast(this)->bar();//在多重继承的情况下调用特定的虚函数
    } 
    void Foo::bar()常量{}
    
    结合
    void Foo::baz(){
    对于每个(m_stuff.begin()、m_stuff.end()、bind(&Foo:framboozle,this,_1));
    对于每个(m_stuff.begin(),m_stuff.end(),[this](StuffUnit&s){framboozle(s);});
    } 
    void Foo::framboozle(StuffUnit和su){}
    std::向量m_stuff;
    
    成员的ptr
    void Foo::boz(){
    bez(&Foo::bar);
    贝兹(Foo::baz);
    } 
    void Foo::bez(void(Foo::*func_ptr)(){
    对于(int i=0;i*func_ptr)();
    }
    }
    

    希望它有助于展示除此->成员之外的其他用法。

    另一种情况是调用运算符时。例如,代替

    bool Type::operator!=(const Type& rhs)
    {
        return !operator==(rhs);
    }
    
    你可以说

    bool Type::operator!=(const Type& rhs)
    {
        return !(*this == rhs);
    }
    
    这可能更具可读性。另一个示例是复制和交换:

    Type& Type::operator=(const Type& rhs)
    {
        Type temp(rhs);
        temp.swap(*this);
    }
    

    我不知道为什么它不是写代码[Stp:Exchange(TEMP)< /C> ],但这似乎很常见。

    < P>我发现了另一个有趣的例子,即C++中有效的C++中的“这个”指针的显式用法。 例如,假设您有一个常量函数,如

      unsigned String::length() const
    
    您不希望为每个调用计算字符串的长度,因此您希望通过如下方式缓存它

      unsigned String::length() const
      {
        if(!lengthInitialized)
        {
          length = strlen(data);
          lengthInitialized = 1;
        }
      }
    
    但这不会编译-您正在更改const函数中的对象

    解决此问题的技巧需要将其强制转换为非常量this:

    然后,你就可以在上面做了

      nonConstThis->lengthInitialized = 1;
    

    虽然我通常并不特别喜欢它,但我见过其他人使用此->只是为了从intellisense获得帮助!

    在少数情况下必须使用
    ,还有一些情况下使用
    指针是解决问题的一种方法

    1) 可用的备选方案:要解决局部变量和类成员之间的歧义

    2) 别无选择:从成员函数返回指向此
    的指针或引用。重载
    运算符+
    运算符-
    运算符=
    等时,这是经常做的(也应该做的):

    class Foo
    {
      Foo& operator=(const Foo& rhs)
      {
        return * this;
      }
    };
    
    这样做允许使用一种称为“”的习惯用法,即在一行代码中对一个对象执行多个操作。例如:

    Student st;
    st.SetAge (21).SetGender (male).SetClass ("C++ 101");
    
    有些人认为这是一致的,而另一些人则认为这是可憎的。把我算在后一组。

    3) 无其他选择:解析从属类型中的名称。这在使用模板时出现,如本例所示:

    #include <iostream>
    
    
    template <typename Val>
    class ValHolder
    {
    private:
      Val mVal;
    public:
      ValHolder (const Val& val)
      :
        mVal (val)
      {
      }
      Val& GetVal() { return mVal; }
    };
    
    template <typename Val>
    class ValProcessor
    :
      public ValHolder <Val>
    {
    public:
      ValProcessor (const Val& val)
      :
        ValHolder <Val> (val)
      {
      }
    
      Val ComputeValue()
      {
    //    int ret = 2 * GetVal();  // ERROR:  No member 'GetVal'
        int ret = 4 * this->GetVal();  // OK -- this tells compiler to examine dependant type (ValHolder)
        return ret;
      }
    };
    
    int main()
    {
      ValProcessor <int> proc (42);
      const int val = proc.ComputeValue();
      std::cout << val << "\n";
    }
    
    #包括
    模板
    阶级地主
    {
    私人:
    瓦尔·姆瓦尔;
    公众:
    ValHolder(const Val&Val)
    :
    mVal(val)
    {
    }
    Val&GetVal(){return mVal;}
    };
    模板
    类处理器
    :
    公谷主
    {
    公众:
    ValProcessor(常量Val和Val)
    :
    瓦尔霍尔德(val)
    {
    }
    Val ComputeValue()
    {
    //int ret=2*GetVal();//错误:没有成员“GetVal”
    int ret=4*this->GetVal();//确定——这告诉编译器检查依赖类型(ValHolder)
    返回ret;
    }
    };
    int main()
    {
    valproc(42);
    const int val=proc.ComputeValue();
    std::cout这个
    指针的主要(或者我可以说,唯一)用途是指向用于调用成员函数的对象

    基于这个目的,我们可以有一些情况下,只有使用
    这个
    指针才能解决这个问题

    例如,我们必须返回一个成员函数中的调用对象,参数为同一类对象:

    class human {
    
    ... 
    
    human & human::compare(human & h){
        if (condition)
            return h;       // argument object
        else 
            return *this;   // invoking object
        }
    };
    

    我确信这是一个重复,但它当然是不可搜索的。这不是第一次,我希望这个指针被称为self!不仅如此,我还希望它是一个引用。同样的:|顺便说一下,原因如下:如果
      nonConstThis->lengthInitialized = 1;
    
    class Foo
    {
      Foo& operator=(const Foo& rhs)
      {
        return * this;
      }
    };
    
    Student st;
    st.SetAge (21).SetGender (male).SetClass ("C++ 101");
    
    #include <iostream>
    
    
    template <typename Val>
    class ValHolder
    {
    private:
      Val mVal;
    public:
      ValHolder (const Val& val)
      :
        mVal (val)
      {
      }
      Val& GetVal() { return mVal; }
    };
    
    template <typename Val>
    class ValProcessor
    :
      public ValHolder <Val>
    {
    public:
      ValProcessor (const Val& val)
      :
        ValHolder <Val> (val)
      {
      }
    
      Val ComputeValue()
      {
    //    int ret = 2 * GetVal();  // ERROR:  No member 'GetVal'
        int ret = 4 * this->GetVal();  // OK -- this tells compiler to examine dependant type (ValHolder)
        return ret;
      }
    };
    
    int main()
    {
      ValProcessor <int> proc (42);
      const int val = proc.ComputeValue();
      std::cout << val << "\n";
    }
    
    class human {
    
    ... 
    
    human & human::compare(human & h){
        if (condition)
            return h;       // argument object
        else 
            return *this;   // invoking object
        }
    };