如果在C ++ setter中使用它是否重要?

时间:2011-09-26 15:54:55

标签: c++ this setter

假设我有一个带有私有变量x的c ++类。对于它的setter,使用this有什么不同吗?是否有可能出现意外/意外行为,我不使用this

设置器:

void setX(double input)
{
   x = input;
}

使用this设置器:

void setX(double x)
{
   this->x = x;
}

7 个答案:

答案 0 :(得分:5)

这两个代码片段(假设它们是内联成员函数,因为没有ClassName::位)完全等效。使用您喜欢的任何一种。我倾向于建议不要将命名参数与成员变量相同;把它们混淆起来太容易了。

答案 1 :(得分:4)

由于类模板的两阶段查找,

可能需要this
  1. 明确声明您的意思是成员
  2. 由于查找规则,编译器可能会假设另一个可见的实体意味着
  3. (参见第一个例子)两者都是等价的。

    在非模板情况下,您通常会避免使用this;生成的代码将是相同的,因此不会有任何差异(参见第二个例子)。 原因是编译器将尝试查找它看到的每个符号。查找的第一个位置是类范围(块和函数范围除外)。如果在那里找到该名称的符号,它将隐式发出this。实际上,成员函数只是具有不可见参数的普通函数。

    class Foo {
        void foo () { x = 0; }
        void bar () const { std::cout << x; }
        void frob();
        int x;
    };
    void Foo::frob() {}
    

    实际上已转化为

    class Foo {        
        int x;
    };
    inline void foo (Foo *const this) { this->x = 0; }
    inline void bar (Foo const * const this) { std::cout << this->x; }
    void frob (Foo * const this) {}
    

    由编译器。


    模板中this的行为示例:

    #include <iostream>
    
    void foo() {
        std::cout << "::foo()\n";
    }
    
    template <typename>
    struct Base {
        void foo() const { std::cout << "Base<T>::foo()\n"; }
    };
    
    template <typename T>
    struct Derived_using_this : Base<Derived_using_this<T> > {
        void bar() const { this->foo(); }
    };
    
    template <typename T>
    struct Derived_not_using_this : Base<Derived_not_using_this<T> > {
        void bar() const { foo(); }
    };
    
    
    int main () {
        Derived_not_using_this<void>().bar();
        Derived_using_this<void>().bar();
    }
    

    输出:

    ::foo()
    Base<T>::foo()
    

    非模板的示例程序集:

    使用this

    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    leave
    ret
    

    没有this

    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    leave
    ret
    

    验证自己:

    test.cc:

    #include <stdio.h> // Don't use this. I just did so for nicer assembly.
    
    class Foo {
    public:
        Foo () : i(0) {}
    
        void with_this() const { printf ("%d", this->i); }
        void without_this() const { printf ("%d", i); }
    private:
        int i;
    };
    
    
    int main () {
        Foo f;
        f.with_this();
        f.without_this();
    }
    

    运行g++ -S test.cc。您将看到一个名为test.s的文件,您可以在那里搜索函数名称。

答案 2 :(得分:2)

当涉及模板时,此变体会产生语法差异。但是,它在语义上是相同的; this->变体让您更清楚地了解当前对象并避免潜在的碰撞。

答案 3 :(得分:2)

void setX(double x)
{
    this->x = x;
}

如果成员变量x被参数x遮挡,则明确需要this->以确保您分配正确的变量。否则就不需要了。

但我不建议你将你的论点命名为与成员变量相同的东西。你提供的第一个例子有更少的陷阱。

答案 4 :(得分:1)

它们之间没有区别。

答案 5 :(得分:1)

虽然您的代码可以运行,但代码很差,可能会让某些人感到困惑。

更好地为“setX()”参数赋予不同的名称。

e.g。

void setX(double new_x)
{
   x = new_x;
}

答案 6 :(得分:0)

没关系。我使用过代码约定,声明应该通过 this 访问所有私有变量,以使代码更具可读性。但除了可读性之外,我认为没有任何区别。