this指针如何使C++成员指针可调用

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
大数据开发治理平台 DataWorks,不限时长
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文介绍了C++中的this指针,它是一个隐藏的指针,用于在成员函数中访问对象实例的成员。文章通过代码示例阐述了this指针的工作原理,以及如何使用指向成员变量和成员函数的指针。此外,还提供了一个多线程爬虫示例,展示this指针如何使成员指针在对象实例上调用,同时利用代理IP和多线程提升爬取效率。

爬虫代理.jpeg

在C++中,this指针是一个隐藏的指针,指向当前对象实例。它在成员函数中自动可用,用于访问该对象的成员变量和成员函数。理解this指针的工作原理有助于理解为什么指向成员的指针是可调用的。在本文中,我们将详细探讨this指针的概念,并通过具体的代码示例说明其在指向成员指针中的应用。

1. 理解this指针

每个非静态成员函数都有一个隐藏的this指针,指向调用该函数的对象。this指针在成员函数内部自动可用,允许函数访问对象的成员。

class MyClass {
   
   
public:
    int value;
    void display() {
   
   
        std::cout << "Value: " << this->value << std::endl;
    }
};

在上述代码中,this->value访问了当前对象的成员变量value

2. 指向成员变量的指针

指向成员变量的指针用于指向类的成员变量。这种指针不能单独使用,必须结合特定的对象实例。

class MyClass {
   
   
public:
    int value;
};

int MyClass::*ptr = &MyClass::value;

MyClass obj;
obj.value = 42;

// 使用成员变量指针访问对象成员
std::cout << "Value: " << obj.*ptr << std::endl;

在这里,ptr是指向成员变量value的指针,必须通过对象实例obj来访问。

3. 指向成员函数的指针

指向成员函数的指针用于指向类的成员函数。这种指针的类型为ReturnType (ClassName::*)(ArgType),其中ReturnType是函数的返回类型,ArgType是函数的参数类型。

class MyClass {
   
   
public:
    void display(int num) {
   
   
        std::cout << "Number: " << num << std::endl;
    }
};

void (MyClass::*funcPtr)(int) = &MyClass::display;

MyClass obj;
(obj.*funcPtr)(42);

在这里,funcPtr是指向成员函数display的指针,通过对象实例obj调用。

4. this指针如何使成员指针可调用

在调用成员函数指针时,编译器隐式地传递了this指针,使得成员函数可以访问当前对象的成员变量。这是为什么成员指针可以通过对象实例调用的原因。

5. 代码示例:使用指针的爬虫示例

我们将实现一个多线程的爬虫示例,使用代理IP技术来提高采集效率。我们假设使用爬虫代理,其域名、端口、用户名和密码分别为proxy.host.cn8080usernamepassword。在示例中,我们将利用C++的成员指针和this指针。

爬虫类设计

首先,我们设计一个爬虫类,其中包括成员函数和指向这些成员的指针。

#include <iostream>
#include <thread>
#include <vector>
#include <curl/curl.h>

//爬虫代理设置(使用亿牛云爬虫代理加强版)
const std::string PROXY = "proxy.host.cn:8080";
const std::string PROXY_USERPWD = "username:password";

// 用于接收curl回调的函数
size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
   
   
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

class WebCrawler {
   
   
public:
    // 成员变量
    std::string response;

    // 成员函数
    void fetchUrl(const std::string& url) {
   
   
        CURL* curl;
        CURLcode res;
        response.clear();

        curl = curl_easy_init();
        if (curl) {
   
   
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
            curl_easy_setopt(curl, CURLOPT_PROXY, PROXY.c_str());
            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, PROXY_USERPWD.c_str());
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
            res = curl_easy_perform(curl);
            if (res != CURLE_OK) {
   
   
                std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
            } else {
   
   
                std::cout << "Data from " << url << ": " << response << std::endl;
            }
            curl_easy_cleanup(curl);
        }
    }

    // 使用成员函数指针调用
    void startMultithreadedCrawl(const std::vector<std::string>& urls) {
   
   
        std::vector<std::thread> threads;
        void (WebCrawler::*funcPtr)(const std::string&) = &WebCrawler::fetchUrl;

        for (const auto& url : urls) {
   
   
            threads.emplace_back(std::thread(funcPtr, this, url));
        }
        for (auto& thread : threads) {
   
   
            if (thread.joinable()) {
   
   
                thread.join();
            }
        }
    }
};

int main() {
   
   
    WebCrawler crawler;
    std::vector<std::string> urls = {
   
   
        "http://example.com",
        "http://example.org",
        "http://example.net"
    };
    crawler.startMultithreadedCrawl(urls);
    return 0;
}

代码解释

  1. WebCrawler类
    • 包含一个成员变量response用于存储HTTP响应。
    • 包含一个成员函数fetchUrl,用于使用CURL库从给定URL抓取数据。
    • 包含一个成员函数startMultithreadedCrawl,用于启动多线程爬取。
  2. 成员函数指针
    • void (WebCrawler::*funcPtr)(const std::string&) = &WebCrawler::fetchUrl; 定义了一个指向成员函数fetchUrl的指针。
    • std::thread(funcPtr, this, url) 通过this指针将成员函数指针与具体的对象实例绑定,在多线程中调用。
  3. 多线程爬取
    • 创建一个包含多个URL的向量。
    • 调用startMultithreadedCrawl函数,在每个线程中通过成员函数指针调用fetchUrl

通过以上示例,我们不仅展示了this指针如何使C成员指针可调用,还展示了在实际应用中如何结合代理IP技术和多线程技术提高爬取效率。希望这些内容能帮助您更好地理解C中的this指针和成员指针的应用。

相关文章
|
3天前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
11天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
18天前
|
C++ 容器
【编程技巧】 C++11智能指针
C++11引入了智能指针以自动管理内存,防止内存泄漏和悬挂指针: - `shared_ptr`:引用计数,多所有权,适用于多个对象共享资源。 - `unique_ptr`:独占所有权,更轻量级,适用于单一对象所有者。 - `weak_ptr`:弱引用,不增加引用计数,解决`shared_ptr`循环引用问题。 ## shared_ptr - 支持引用计数,所有者共同负责资源释放。 - 创建方式:空指针、new操作、拷贝构造/移动构造,以及自定义删除器。 - 提供`operator*`和`operator-&gt;`,以及`reset`、`swap`等方法。 ## unique_ptr
228 1
|
19天前
|
C++
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
18 0
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
|
3天前
|
安全 编译器 程序员
【C++11】智能指针
【C++11】智能指针
3 0
|
11天前
|
C++
【C++】string类的使用④(常量成员Member constants)
C++ `std::string` 的 `find_first_of`, `find_last_of`, `find_first_not_of`, `find_last_not_of` 函数分别用于从不同方向查找目标字符或子串。它们都返回匹配位置,未找到则返回 `npos`。`substr` 用于提取子字符串,`compare` 则提供更灵活的字符串比较。`npos` 是一个表示最大值的常量,用于标记未找到匹配的情况。示例代码展示了这些函数的实际应用,如替换元音、分割路径、查找非字母字符等。
|
11天前
|
编译器 C++
【C++】类和对象⑤(static成员 | 友元 | 内部类 | 匿名对象)
📚 C++ 知识点概览:探索类的`static`成员、友元及应用🔍。
|
12天前
|
存储 安全 程序员
|
19天前
|
C++
C++指针
C++指针
10 0