首页 > 其他分享 >this指针小总结

this指针小总结

时间:2024-06-19 13:31:55浏览次数:24  
标签:总结 函数 int 成员 value MyClass 指针

目录

this指针小总结

this指针在类中和全局中的区别

this指针和普通指针的区别

this指针的用法


this指针小总结

在C++中,this指针是一个隐式的、非静态的成员指针,它指向调用它的对象的地址。每个非静态成员函数都含有一个this指针,该指针在成员函数中用于访问调用它的对象的成员。

以下是关于this指针的一些总结:

隐式存在:在成员函数的内部,this指针是隐式存在的,你不需要(也不能)明确地声明它。

指向当前对象:this指针指向调用成员函数的当前对象。

类型:this指针的类型是指向类类型的指针,即ClassName* const this。注意,this指针是常量指针,你不能改变this指针使其指向其他对象,但你可以改变它所指向的对象的内容。

用途:

区分成员变量和局部变量:如果成员变量和函数参数或局部变量重名,可以使用this->来明确指定成员变量。
返回当前对象的引用或指针:在成员函数中,你可以返回*this(对象的引用)或this(对象的指针)来支持链式操作。
传递给其他函数:你可以将this指针作为参数传递给其他函数,但通常这并不是好的做法,除非你有明确的理由。

静态成员函数:静态成员函数没有this指针,因为它们不与任何对象实例关联。

构造函数和析构函数:在构造函数和析构函数中,this指针特别有用,因为它们是在对象完全构造或完全析构之前/之后调用的。使用this指针可以在构造函数中初始化其他对象或在析构函数中执行清理操作。

注意事项:虽然this指针在大多数情况下是隐式的,但你不应该直接修改它的值(因为它是常量指针)。此外,也不应该保存this指针的副本并在对象析构后使用它,因为这可能导致悬垂指针(dangling pointer)问题。

下面是一个简单的示例,展示了如何在成员函数中使用this指针:

class MyClass {
public:
    int value;

    MyClass(int v) : value(v) {}

    void printValue() {
        std::cout << "Value of this object: " << this->value << std::endl;
        // 或者简单地使用 value,因为 this-> 是隐式的
    }

    MyClass& setValue(int v) {
        this->value = v;
        return *this; // 返回当前对象的引用,支持链式操作
    }
};
int main() {
    MyClass obj(10);
    obj.printValue(); // 输出 "Value of this object: 10"
    obj.setValue(20).printValue(); // 输出 "Value of this object: 20",链式操作
    return 0;
}

this指针在类中和全局中的区别

在C++中,this指针只在类的非静态成员函数中存在,而在全局范围内,是没有this指针的。这是一个非常关键的区别,因为this指针的用途和上下文完全与类的实例(对象)相关。

类中的this指针

在类的非静态成员函数中,this指针是一个指向调用该函数的对象的指针。它用于访问对象的成员变量和成员函数。当你在成员函数内部引用类的成员时,编译器会隐式地使用this指针(尽管你通常不需要显式地写出this->)。

示例:

class MyClass {
public:
    int x;

    MyClass(int value) : x(value) {}

    void printValue() {
        std::cout << "Value of x: " << this->x << std::endl; // 也可以简写为 std::cout << "Value of x: " << x << std::endl;
    }
};

int main() {
    MyClass obj(10);
    obj.printValue(); // 输出 "Value of x: 10"
    return 0;
}


在这个例子中,this指针指向obj对象,并且this->x(或简单地x)引用了obj的x成员。

全局范围中的this指针

在全局范围(包括函数外部和静态成员函数内部)中,没有this指针的概念。这是因为全局函数和静态成员函数不与任何特定的类实例关联。它们可以在没有对象的情况下被调用,因此没有指向“当前对象”的指针。

示例:

int globalVar = 10;

class MyClass {
public:
    static void printGlobalVar() {
        std::cout << "Value of globalVar: " << globalVar << std::endl; // 静态成员函数不能直接访问类的非静态成员
    }
};

int main() {
    MyClass::printGlobalVar(); // 输出 "Value of globalVar: 10"
    return 0;
}


在这个例子中,printGlobalVar是一个静态成员函数,它只能访问全局变量或类的静态成员,因为它没有与任何特定的类实例关联。因此,在静态成员函数中,你不能使用this指针。

总结:this指针只在类的非静态成员函数中存在,并用于引用调用该函数的对象的成员。在全局范围(包括静态成员函数)中,没有this指针的概念。

this指针和普通指针的区别

this指针和普通指针在C++中有几个关键的区别:

存在性和可见性:

this指针:它只在类的非静态成员函数的内部隐式存在,并且你不需要(也不能)显式地声明它。在成员函数内部,你可以通过this指针来访问对象的成员,但通常可以省略this->前缀,因为编译器会自动处理。
普通指针:它是一个显式声明的变量,你可以在任何地方声明和初始化它。它可以是任何类型的指针,用于指向该类型的对象或变量。

用途和上下文:

this指针:它总是指向调用成员函数的当前对象。它用于访问和修改对象的成员变量,以及调用其他成员函数。在某些情况下,如链式调用或需要区分成员变量和局部变量时,this指针特别有用。
普通指针:它可以用于多种目的,包括指向对象的内存地址、传递参数、访问和修改对象的成员、在数据结构(如链表、树)中建立连接等。

生命周期和绑定:

this指针:它的生命周期与成员函数的执行期间相同。当成员函数被调用时,this指针被自动绑定到调用该函数的对象的地址上。一旦成员函数执行完毕,this指针就消失了。
普通指针:它的生命周期取决于其声明位置和范围。它可以在函数内部、全局范围或类的成员变量中声明。它的值可以在程序的任何时候被修改,以指向不同的地址或对象。

类型和安全性:

this指针:它的类型是类的指针(例如ClassName*),并且它总是指向类的实例。由于它是隐式的,因此不存在类型错误或空指针解引用的风险(除非在成员函数中显式地使用了一个未初始化的指针)。
普通指针:它的类型可以是任何数据类型的指针(如int*, float*, MyClass*等)。你需要确保在使用它之前正确地初始化了它,并且它指向了一个有效的内存地址。否则,你可能会遇到空指针解引用、野指针或类型不匹配等错误。

静态成员函数:

this指针:在静态成员函数中不存在this指针,因为静态成员函数不与任何特定的对象实例关联。
普通指针:静态成员函数可以像其他函数一样使用普通指针作为参数或局部变量。

总结:this指针是C++中类的一个特殊特性,它隐式地存在于非静态成员函数中,并用于访问和修改对象的成员。而普通指针是一个通用的编程概念,可以在任何地方声明和使用,用于指向和访问内存中的数据和对象。

this指针的用法

this指针在C++中主要用于指代当前对象实例的指针。在类的非静态成员函数中,你可以通过this指针来访问或修改对象的成员变量或调用其他成员函数。尽管在大多数情况下,你可以直接访问类的成员,而无需显式使用this指针,但在某些情况下,this指针会特别有用。

以下是一些this指针的常见用法:

1. 区分成员变量和局部变量

当成员变量和局部变量的名称相同时,你可以使用this指针来区分它们。

class MyClass {
public:
    int x;

    MyClass(int x) : x(x) {}

    void printX() {
        int x = 10; // 局部变量
        std::cout << "Local x: " << x << ", Member x: " << this->x << std::endl;
    }
};

2. 链式调用

在返回当前对象引用(*this)的成员函数中,你可以实现链式调用。

class MyClass {
public:
    int value;

    MyClass(int value) : value(value) {}

    MyClass& setValue(int newValue) {
        this->value = newValue;
        return *this; // 返回当前对象的引用
    }
};

// 使用链式调用
int main() {
    MyClass obj(10);
    obj.setValue(20).setValue(30); // obj的value现在是30
    return 0;
}

3. 作为函数参数

在某些情况下,你可能需要将this指针作为参数传递给另一个函数或成员函数。

class MyClass {
public:
    void someFunction();
    void anotherFunction(MyClass* ptr);
};

void MyClass::someFunction() {
    anotherFunction(this); // 将this指针传递给另一个成员函数
}

void MyClass::anotherFunction(MyClass* ptr) {
    // 使用ptr来访问调用someFunction的对象
    std::cout << ptr->value << std::endl; // 假设MyClass有一个value成员变量
}

4. 在运算符重载中

在重载运算符时,this指针通常用于指代左侧的运算对象。


class MyClass {
public:
    int value;

    MyClass(int value) : value(value) {}

    MyClass operator+(const MyClass& other) {
        return MyClass(this->value + other.value); // 使用this指针指代左侧的运算对象
    }
};

// 使用
MyClass a(10);
MyClass b(20);
MyClass c = a + b; // c的value现在是30

5. 在拷贝构造函数和赋值运算符中

在这些特殊的成员函数中,this指针通常用于区分源对象(被拷贝或赋值的对象)和目标对象(正在被创建或修改的对象)。

class MyClass {
public:
    int* ptr;

    MyClass(int value) : ptr(new int(value)) {}

    // 拷贝构造函数
    MyClass(const MyClass& other) : ptr(new int(other.ptr[0])) {
        // this->ptr现在指向新分配的内存,其中存储了other.ptr指向的值
    }

    // 赋值运算符
    MyClass& operator=(const MyClass& other) {
        if (this != &other) { // 检查自赋值
            delete ptr; // 释放旧内存
            ptr = new int(other.ptr[0]); // 分配新内存并复制值
        }
        return *this;
    }

    // 析构函数(别忘了实现它来处理动态分配的内存)
    ~MyClass() {
        delete ptr;
    }
};

请注意,在使用this指针时要特别小心,以避免自引用和自赋值等问题。此外,当你处理动态分配的内存时,务必确保在析构函数、拷贝构造函数和赋值运算符中正确地管理内存,以避免内存泄漏或双重释放等问题。

标签:总结,函数,int,成员,value,MyClass,指针
From: https://blog.csdn.net/2401_83427936/article/details/139799778

相关文章

  • JavaScript基础部分知识点总结(Part2)
    初识JavaScript1.JavaScript是什么JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(Script是脚本的意思)脚本语言:不需要编译,运行过程中由js解释器(js引擎)逐行来进行解释并执行现在也可以基于Node.js技术进行服务器端编程2.JavaScript的作用表单动态校......
  • 【笔记】指针函数中可以返回什么样的指针,从两个例子开始(上)
    关于指针函数的两个例子:第一个例子:下面这段代码是否能正确运行?#include<stdio.h>char*get_string(){char*s="hello";returns;}intmain(){char*p;p=get_string();printf("p=%s\n",p);}因为s指向的是字符串常量,被存储在静态区(......
  • 文献总结:ON THE TRAINING AND GENERALIZATION OF DEEP OPERATOR NETWORKS(关于深度算
    ONTHETRAININGANDGENERALIZATIONOFDEEPOPERATORNETWORKS(关于深度算子网络的训练和泛化)remark:相较于之前的文章,这篇更新了两个重要定理的证明!算子网络DeepONet由两个网络构成,即trunk网络和branch网络,通常是同时训练这两个网络,这相当于是在高维空间中解决复杂的优......
  • Reids高频面试题汇总总结
    一、Redis基础Redis是什么?Redis是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令来操作这些数据结构。Redis的主要特点是什么?高性能:Redis将数据存储在......
  • G1《狙击手幽灵战士:契约2》总结
    《狙击手幽灵战士:契约2》​ 高考完果然除了强基乱起八糟的以外,闲的屁事没有。所以就干脆肝爆了这块老游戏。游玩时间是\(24.6.10\sim18\),大约平均每天有\(5h\)吧。​ 游戏主要讲述了一个国际组织内的一个超级特工帮助消灭某国家反叛势力从而维护世界和平的故事,剧情设定就比......
  • 【C语言】数组参数和指针参数详解
    在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?1一维数组传参#include<stdio.h>voidtest(intarr[])//ok?{}voidtest(intarr[10])//ok?{}voidtest(int*arr)//ok?{}voidtest2(int*arr[20])//ok?{}voidtest2(int**arr)//ok?......
  • 亏钱、踩坑总结的经验之:野鸡驾校
    宝子们小心野鸡驾校!我的钱就没了,教训深刻!报名了一个野鸡驾校,交了7000多的报名费。当时教练说包过,后面说要有驾校培训合格证才会给我发证,一直墨迹。说好的2月份拿证,现在都6月份了,驾校一点消息都没有,打电话对方都不接。我去驾校一看,驾校老板都外出了,去了之后才知道他们老板也跑......
  • 【面试八股总结】Redis数据结构及底层实现
    一、五种基本数据结构        Redis提供了丰富的数据类型,常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)结构类型结构可存储值结构读写能力使用命令底层数据结构String字符串、整数或浮点数对字符串或字符串的一部分进行操作,对整数或浮点......
  • 当char型变量遇上char*型的指针
    #include<stdio.h>intmain(void){ char*i=(char*)0x1111; printf("size=%d%d\n",sizeof(i),sizeof((char*)0x11));//sizei=8bytes,size(char*)0x11=8bytes,cause0x11isconveredtochar*,char*isaponinterandhas64......
  • 线程最全面总结
    多线程开发:并发编程多线程程序的好处:提高程序的效率多线程程序如何开发?方式1:Thread类(java语言提供的现成的线程类)1.创建一个子类,继承Thread类(创建的子类:也是线程类)2.在子类中,编写让线程帮助完成的任务(任务代码)//重写Thread类中的run方法(线程......