C++(this指针)

一、this指针:

1.作用:

类的每个成员函数中都有一个指针叫this,指向调用成员函数的那个对象。

1.是一个指针,指向对象本身,

2.this只能在类的内部使用,

在类的内部调用成员都是使用this调用的,可以省略

示例2:

#include <iostream>
using namespace std;
class Person
private:
    int age;
public:
    Person(int age)
    {
        this->age = age;//this->age 是指向当前构造函数的对象的age
    }
    void show()
    {
        cout<<this->age<<endl;//就算这里不写this,系统也会给我们补上this,在成员函数中调用成员都是通过this指针调用的。不写this属于隐式调用this
    }
};
int main()
{
     Person p(1);//创建对象p,所以这里执行构造函数时,构造函数的this指向p
     p.show();//show中this指向p,因为p调用show
}

2.this的一般用法

指向对象本身

this指向的是哪个对象?指向当前正在调用成员函数的对象。

this存在的意义:在类的内部,将当前对象当做参数进行传递

示例:

#include <iostream>
using namespace std;
​
class Person;
void printPerson(Person* p);
​
class Person
{
private:
    int age;
    int score;
public:
    Person(int age, int score)
    {
        this->age = age;
        this->score = score;
    }
    void show()
    {
        cout<<age<<" "<<score<<endl;
    }
    void doSomething()
    {
        printPerson(this);//当前对象  person*  p对象的指针传递过去了
    }
};
void printPerson(Person* p)//Person* ptr_p = p对象的指针
{
    p->show();
}
int main()
{
    Person p(10, 20);
    p.doSomething();
​
    Person p2(30, 40);
    p2.doSomething();
    return 0;
}

类声明:

#include <iostream>
using namespace std;
​
class B;//声明对象时,不创建对象
class A
{
public:
    B* p;
    A()
    {
        p = new B;
    }
};
class B
{
};
int main()
{
    A a;//编译错误
    return 0;
}

练习1:

Person类,包含私有属性:姓名name,性别bool gender,年龄age,另一个对象的指针 Person *lover(爱人);

1.构造函数初始化成员变量 name gender

2.成员函数setAge给年龄赋值

3.成员函数marry(Person& other) 输出name"和"other.name"喜结良缘!";

4.成员函数show(); 输出"大家好!我是"gender,name,今年"age;

输出"爱人是:"lover->name;

private:
    string name;
    bool gender;
    int age;
    Person *lover;

#include <iostream>
using namespace std;
​
class Person
{
    string name;
    bool gender;
    int age;
    //指向另外一个person类型的对象指针
    Person* lover;
public:
    Person(string name,bool gender):name(name),gender(gender)
    {
    }
    void setAge(int age)
    {
        this->age = age;
    }
    void marry(Person& other)//p2
    {
        //当前调用者(邓超)的爱人是孙俪
        this->lover = &other;
        //孙俪的爱人是邓超
        other.lover = this;
        cout<<this->name<<" "<<other.name<<"在一起"<<endl;
    }
    void show()
    {
        cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<",今年"
           <<age<<"岁"<<endl;
        cout<<"我的爱人是"<<lover->name<<endl;
    }
};
int main()
{
    Person p1("邓超",true);
    p1.setAge(48);
​
    Person p2("孙俪",false);
    p2.setAge(24);
​
    p1.marry(p2);
​
    p1.show();
    p2.show();
​
    return 0;
}

二、拷贝构造函数

思考:下面代码输出几次 "student"

class Student
{
public:
    Student()
    {
        cout<<"student"<<endl;
    }
private:
    //string m_name;
};
int main()
{
    Student stu1;//创建对象调用构造函数
    Student stu2 = stu1;//使用同类型一个对象初始化另一个对象,这就是复制对象,会调用拷贝构造函数
    Student stu3(stu1);//使用同类型一个对象初始化另一个对象,这就是复制对象,会调用拷贝构造函数
}

1.声明:

函数名(类名)(const 类名 &对象名)

使用一个对象初始化另一个对象的时候调用拷贝构造

拷贝构造函数的参数列表必须是 const 类名 &对象名。

示例1:

#include <iostream>
using namespace std;
​
class Person
{
private:
    int age;
public:
    Person(int age)
    {
        this->age = age;
    }
    //根据参数列表判断这是拷贝构造函数,Person类型的拷贝构造函数,参数必须是Perosn类型
    Person(const Person& other)
    {
        cout<<"拷贝构造"<<endl;
        this->age=other.age;
    }
    void show()
    {
        cout<<this->age<<endl;
    }
};
int main()
{
    Person a(19);
    cout<<"start"<<endl;
    Person b(a);//调用对象b 的拷贝构造函数
    Person c = a;
    cout<<"end"<<endl;
    b.show();
}

2.默认拷贝构造函数

1)在没有显式的定义拷贝构造函数时,系统会自动生成一个拷贝构造函数,

功能:将成员变量逐个赋值

2)如果显式的定义拷贝构造函数,并且运行时执行了拷贝构造函数,

那么默认拷贝构造函数和默认构造函数都不会被调用了

3)创建一个对象的时候,只会调用一个构造函数

默认的构造:一个构造函数都没有

默认的拷贝构造:没有拷贝构造存在

写了拷贝构造的时候,默认的构造函数还在不? 不在了

示例2:

#include <iostream>
using namespace std;
​
class Person
{
private:
    int age;
public:
    Person(int age):age(age)
    {
    }
    //Person类中没有显式的定义拷贝构造函数
    int getAge()
    {
        return age;
    }
};
​
int main()
{
    Person* p = new Person(19);//在堆空间创建一个对象
    Person* p2 = new Person(*p);//*p是一个Person对象,这里是使用同类型的一个对象初始化另一个对象,调用拷贝构造函数,但是在Person中没有显式的定义拷贝构造函数,所以这里调用默认拷贝构造函数
    cout<<p->getAge()<<endl;,
    cout<<p2->getAge()<<endl;
}

总结:

1. 如果没有自定义的拷贝构造函数则系统自动生成一个默认的拷贝构造函数

Empty(const Empty& o)
{
    //this->age = o.age;
}

2. 当使用一个对象实例化另外一个新对象时,系统自动调用拷贝构造函数

Person p;//构造函数
Person p2 = p;//拷贝构造函数
Perosn p3(p);//拷贝构造函数

3. 系统默认拷贝构造函数的功能:逐个对成员变量进行赋值

4. 显示的定义了拷贝构造函数,系统默认的就不存在了,

函数的功能(对变量进行的赋值),就由我们自己来完成了

3*.拷贝构造函数调用三种情况:

### C++ 中 `this` 指针的概念 在 C++ 编程语言中,`this` 是一个特殊的指针变量,在类的非静态成员函数内部自动存在。它指向当前正在被操作的对象实例[^1]。通过使用 `this` 指针,可以访问对象的数据成员以及成员函数。 #### 为什么需要 `this` 指针? 当在一个类的方法中定义了一个局部变量或者参数名与数据成员同名时,可能会发生命名冲突。此时可以通过 `this->` 来区分它们,其中 `this` 明确表示的是当前对象的数据成员[^2]。 --- ### `this` 指针的主要用途 以下是几种常见的场景下 `this` 的应用方式: #### 1. 解决名称冲突 如果某个方法接收的参数名字与其所属类中的成员变量相同,则可以用 `this` 指向实际的成员变量来消除歧义。 ```cpp #include <iostream> using namespace std; class Person { private: string name; public: void setName(string name) { this->name = name; // 使用 this 区分成员变量和形参 } void getName() const { cout << "Name is: " << name << endl; } }; int main(){ Person p; p.setName("Alice"); p.getName(); return 0; } ``` 上述例子展示了如何利用 `this` 避免因重名而产生的混乱情况。 #### 2. 返回当前对象本身 返回 *current object* 可用于链式调用(chaining),即连续执行多个操作于同一个对象之上而不需重复指定目标实体。 ```cpp class Counter{ private: int count; public: Counter():count(0){} Counter& increment(){ ++count; return *this; // 返回自身的引用以便支持连贯调用 } void displayCount()const{ cout<<"Current Count:"<<count<<endl; } }; // 测试部分省略... ``` 这里展示了一种模式——允许像这样写代码:`counter.increment().increment()`[^3]。 #### 3. 调用其他成员函数 有时候可能希望从某成员函数内部去触发另一个成员函数的动作;这时就可以借助 `this` 实现这一点。 ```cpp void bar() { std::cout << "Inside bar()" << std::endl; this->foo(); // 利用 this 呼叫另一项功能 } ``` 此片段取自先前提供的资料说明了怎样借由 `this` 执行额外的功能呼叫。 #### 4. 动态分配内存给对象副本 另外一种常见情形是在构造器里复制传入的对象属性值到新建立出来的个体之中,这时候也可以运用 `this`. ```cpp Person(const Person &other){ *(this)= other;// 将 another 对象的内容赋值给自己 } ``` 注意这里的语法结构意味着把右侧表达式的全部字段逐一对应拷贝至左侧所代表的新建体当中[^4]。 --- ### 总结注意事项 尽管 `this` 提供了许多便利之处,但也有一些地方值得特别留意: - 它仅存在于非静态成员函数之内; - 不可手动修改其地址值; - 当涉及多线程环境下的共享资源管理时要格外小心同步问题等等。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值