【C++】This指针和复制构造函数

简介: 【C++】This指针和复制构造函数

在声明一个类的时候,是没有分配存储空间的,只有在真正定义一个对象的时候,程序才会为这个对象分配相应的存储空间。

如果定义了多个对象,这些对象都有自己的存储空间,但是这些对象都是用相同的成员方法的。


当不同的对象调用成员方法时,怎么保证就是这个对象的成员?


this指针


在每个成员函数中,都包含一个特殊的指针。

这个指针的名字是固定的,就是this指针。

this指针是指向类对象的指针,它的值是当前被调用的所在对象的地址!


this指针是指向本类对象的指针,它作为参数传递给成员函数

this指针是隐式使用的。由编译器自动实现,我们不必人为的在形参中添加this指针。


因为this表示这个对象的指针,所以*this就表示这个对象了


(*this).调用成员变量/函数和this->调用成员变量/函数,是一样的效果!

注意给*this添加括号,因为.运算符的优先级比较高


复制构造函数


复制构造函数和普通构造函数有一些相似处的,也没有返回值,类名作为函数名!


复制构造函数一种特殊的构造函数,在创建一个新的对象时将其他对象作为参数时,

编译器将会调用复制构造函数。不提供时使用默认构造函数。默认构造函数内部各个成员变量赋值。

创建之后,新对象是老对象的副本,二者值相同。但具有不同的存储空间。


CTime(CTime& time);//使用类名对象作为参数,传引用


调用复制构造函数的时机:


在什么情况下使用复制构造函数


1.以其他对象作为参数创建新对象时。


比如:创建一个新的对象的时候,把原来的一个对象作为参数传递给新的对象作为构造函数


CTime time;
CTime time2(time);//会自动执行复制构造函数,复制成员等



CTime::CTime(CTime& time){
    m_hour = time.m_hour;
    m_minute = time.m_minute;
    m_second = time.m_second;
}


CTime time;
    time.setHour(10);//通过成员方法设置值
    time.setMinute(20);
    time.setSecond(30);
    cout << time.getHour() << ":" << time.getMinute() << ":" << time.getSecond() << endl;
    //输出结果: 10:20:30
    CTime time2(time);
    cout << time2.getHour() << ":" << time2.getMinute() << ":" << time2.getSecond() << endl;

(注意,构造函数实现的时候,需要在其他函数前面先实现)

复制构造函数也是构造函数的一种!


2.类对象(传值)作为函数参数时。


#include <iostream>
#include "Time.h"
using namespace std;
void func(CTime time){
    cout << time.getHour()<<endl;
}
int main(){
    CTime time;
    time.setHour(10);//通过成员方法设置值
    time.setMinute(20);
    time.setSecond(30);
    CTime time2(time);//第一次调用复制构造函数
    func(time);//第二次调用复制构造函数  复制给func中的形参time
    cout << time.getHour() << ":" << time.getMinute() << ":" << time.getSecond() << endl;
    //输出结果: 10:20:30
    cout << time2.getHour() << ":" << time2.getMinute() << ":" << time2.getSecond() << endl;
    getchar();//这句是为了防止输出窗口秒关闭
    return 0;
}


3.类对象作为函数返回值时。


#include <iostream>
#include "Time.h"
using namespace std;
void func(CTime time){
    cout << time.getHour()<<endl;
}
CTime func1(CTime time){
    //复制给func1中的形参time 也会调用一次复制构造函数
    cout << time.getHour() << endl;
    return time;//time在返回的时候会复制给返回的值,这个时候会调用复制构造函数
}
int main(){
    CTime time;
    time.setHour(10);//通过成员方法设置值
    time.setMinute(20);
    time.setSecond(30);
    CTime time2(time);//第一次调用复制构造函数
    func(time);//第二次调用复制构造函数  复制给func中的形参time
    CTime time3 = func1(time);//第三次和第四次调用复制构造函数
    cout << time.getHour() << ":" << time.getMinute() << ":" << time.getSecond() << endl;
    //输出结果: 10:20:30
    cout << time2.getHour() << ":" << time2.getMinute() << ":" << time2.getSecond() << endl;
    getchar();//这句是为了防止输出窗口秒关闭
    return 0;
}



上面就是复制构造函数使用的三种情形!


如果我们把复制构造函数 CTime::CTime(CTime& time)修改为CTime::CTime(CTime time)

CTime& time是一个引用类型的参数,现在将引用去掉的话,就满足了调用复制构造函数中的一种,以类对象(传值)作为函数参数时,

这样在使用的时候,就会造成死循环!


所以注意复制构造函数是传引用来实现的!


我们使用类对象作为函数参数的时候,以及返回一个对象的时候,代价是很大的,

因为伴随着对象的创建和销毁,还伴随着复制构造函数的调用, 所以一般使用传引用来规避这种代价!

引用传递:

形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。


源代码下载地址:

GITHUB源码下载地址: 点我进行下载


目录
相关文章
|
12天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
40 5
|
18天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
48 4
|
19天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
45 4
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
2月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
44 1
|
2月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
32 2
|
2月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
38 2
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
20 1
|
2月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
2月前
|
存储 C++ 索引
C++函数指针详解
【10月更文挑战第3天】本文介绍了C++中的函数指针概念、定义与应用。函数指针是一种指向函数的特殊指针,其类型取决于函数的返回值与参数类型。定义函数指针需指定返回类型和参数列表,如 `int (*funcPtr)(int, int);`。通过赋值函数名给指针,即可调用该函数,支持两种调用格式:`(*funcPtr)(参数)` 和 `funcPtr(参数)`。函数指针还可作为参数传递给其他函数,增强程序灵活性。此外,也可创建函数指针数组,存储多个函数指针。