为啥我们使用 'this->' 而不是 'this'。访问成员?

Posted

技术标签:

【中文标题】为啥我们使用 \'this->\' 而不是 \'this\'。访问成员?【英文标题】:Why do we use 'this->' and not 'this.' to access members?为什么我们使用 'this->' 而不是 'this'。访问成员? 【发布时间】:2009-03-25 07:01:50 【问题描述】:

我正在查看一个人用 C++ 为 FaceBook 制作的库。头文件是这样的:

#ifndef __FACEBOOK_H__
#define __FACEBOOK_H__

/**
 * Facebook Class 
 * Joel Seligstein
 * Last mod: Aug 22, 2006
 *
 * This is the beginnings of a facebook class set and REST client.  Its not documented
 * yet nor nearly complete.  But this is a release to demonstrate its usefulness.  
 * Please email joel@seligstein.com with suggestions or additions.
 *
 * TODO: Create classes/parsers for each request type
 * TODO: Linux URL launcher
 */

//uncomment to have verbose output turned on
//#define fb_debug 1

//define which platform you're compiling for
#define fb_windows 1
//#define fb_linux 1

#include <string>
#include <sstream>
#include <list>
using namespace std;

#ifdef fb_windows
#include <windows.h>
#endif

#include "curl/curl.h"
#include "xmlParser/xmlParser.h"
#include "md5.h"

class facebook

    public:
        //app/session vars
        string api_key;
        string secret;
        string token;
        string server;
        string session_key;
        string session_secret;
        string uid;
        bool has_session;

        facebook( string my_key, string my_secret, string my_server );
        bool authenticate( );
        bool request( string method, list<string> params, string *res );
        bool load_token( );
        void launch_login( string url );
        bool get_session( );
        void clean_up( );

    private:
        //curl info
        CURL *curl;
        CURLcode res;
        int call_id;

        //internal functions
        string get_signature( list<string> params );
        static string md5( string str );
        static string get_param_string( list<string> params, bool separate );
        static size_t write_callback( void *ptr, size_t size, size_t nmemb, void *userp );
;

#endif //__FACEBOOK_H__

然后在cpp文件里面,我的问题是关于这个的,下面是构造函数:

facebook::facebook( string my_key, string my_secret, string my_server )

    this->api_key = my_key;
    this->secret = my_secret;
    this->server = my_server;
    this->has_session = false;
    this->call_id = 0;

为什么他们使用-&gt; 运算符而不是.

我对@9​​87654325@ 直接在内存中访问该类型的属性和方法的理解有限,但我很困惑,由于无知,我希望看到:

facebook::facebook( string my_key, string my_secret, string my_server )

    this.api_key = my_key;
    this.secret = my_secret;
    this.server = my_server;
    this.has_session = false;
    this.call_id = 0;

我只想知道为什么-&gt; 用于点符号的背后的理论。


更新: 对于与我在同一条船上并学习 C++ 的任何其他人。我已经扩展了成员在此问题中发布的示例。我还包含在成员字段的初始化列表中。

#include "stdafx.h"
#include <iostream>
using namespace std;

class A 
private:
    int x;
public:
    A() : x(0)
    int getX() const return x;
    void setX(int xx) x += xx;
;

int main()

    A a;

    a.setX(13);

    A *pa = &a;

    pa->setX(2);

    A b = a;

    b.setX(5);

    cout << "a" << a.getX() << endl;

    cout << "a*" << pa->getX() << endl;

    cout << "b" << b.getX() << endl;

    return 0;

【问题讨论】:

【参考方案1】:

this 是指向当前对象的指针,即class A 的内部方法(或构造函数),this 的类型为A *

(请注意,如果方法被标记为const,则this 的类型为A const *。)

因此使用-&gt;(仅为指针设计)而不是.(仅为类对象A或对类对象的引用A&amp;设计)。

【讨论】:

感谢您的回答。在什么情况下会使用点符号? 如果您没有指针对象而是引用,例如字符串 b = "asdfghjklö"; b = b.substr(0,5);这是调用字符串对象 b 的 substr 函数【参考方案2】:

在 C++ 中,this 是指向 self 对象的指针。它是 C++ 早期版本的遗留物,在它有引用之前。如果现在将this 添加到语言中,它可能是一个引用,您可以使用. 表示法。

【讨论】:

C 中没有“this”。但如果我没记错的话,C++ 的第一个版本没有引用。 对于'this'不是参考的原因,你可以检查这个问题:***.com/questions/645994/…【参考方案3】:

因为在类或结构成员内部,“this”是一个指向当前实例的特殊指针。

任何时候通过指针访问类或结构的成员时,都会使用 -> 运算符。

如果您通过非指针(通常是引用)访问它们,则使用点运算符。

值得注意的是 this-> 语法不是必需的,除非在某些形式的模板实例化中。不过,很多人出于风格原因选择使用它。在 S.O. 上有几个与此背后的基本原理相关的问题。已经。

【讨论】:

【参考方案4】:

你可以考虑下面的例子。

class A 
    int x;
public:
    int getX() const return x;
    void setx(int xx) x = xx;
;

int main()

    A a;

    a.setX(13);
    cout << a.getX() << endl;

    A *pa = &a;

    cout << pa->getX() << endl;

    return 0;

请注意,点运算符(.)用于直接用对象a调用A的成员函数。通过 A 类型的指针 (A *pa = &a) 间接调用 A 的成员函数时使用箭头运算符 (->)。

在 C++ 中,this 是指向调用对象的指针。因此我们也可以如下定义 A::getX() 函数:

int getX() const return this->x;

或者:

int getX() const return (*this).x;

this 是对象 A 的指针,因此 *this 取消引用它。所以我们可以使用上面的两个函数。

【讨论】:

谢谢我使用了你的例子,并在理解它的同时对其进行了一些扩展。我还包含了初始化列表功能。再次欢呼。 +1;【参考方案5】:

如前所述,这是一个指针,而不是一个引用。因此,您需要大致(但不完全相同)的 -> 运算符:(*this)。

它们的不同之处在于您可以在类中重载 -> 运算符或 * 运算符,并且可以具有不同的语义。事实上,如果一个类重写了 operator-> 并且返回的值不是原始指针,编译器将继续将 operator-> 应用于返回的对象,直到它到达本地指针。操作员 。不能超载。

在您指出的构造函数中,使用 this 是完全可选的,因为没有名称冲突,代码可以直接命名属性而无需进一步限定。

facebook::facebook( string my_key, string my_secret, string my_server )

    api_key = my_key;
    secret = my_secret;
    server = my_server;
    has_session = false;
    call_id = 0;

更好的解决方案是使用初始化列表。如果你有兴趣学习 C++ 谷歌。

【讨论】:

谢谢我刚刚用谷歌搜索过。在 c# 中,我们使用 base 关键字来初始化带有参数的父类型构造函数。我对可以使用初始化列表以相同方式初始化事实字段非常感兴趣。感谢您的评论! :-) 初始化列表不仅用于调用基类构造函数,而且是初始化属性的地方。在 内,属性已默认初始化,您正在重写它们。初始化列表是必须的,因为它们不能被默认初始化。【参考方案6】:

因为“this”是一个特殊的指针,指向当前对象,我们使用“->”通过指针和“.”来访问对象的成员。用于直接调用对象的成员。

【讨论】:

以上是关于为啥我们使用 'this->' 而不是 'this'。访问成员?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 string_view 而不是广义的 container_view<T>?

为啥使用 array($this,'function') 而不是 $this->function()

为啥我不能使用常量而不是 this.item.number?

为啥 BCL 集合使用结构枚举器,而不是类?

为啥 WCF 会返回 myObject[] 而不是 List<T> 像我期望的那样?

如果“struct”和“class”是同一个东西,那么为啥在 template<class T> 中只使用“class”而不是“struct”?