【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源码下载地址:点我进行下载

本文章由[谙忆]编写, 所有权利保留。
欢迎转载,分享是进步的源泉。

转载请注明出处:http://chenhaoxiang.cn

本文源自人生之旅_谙忆的博客

时间: 2024-09-14 04:33:15

【C++】This指针和复制构造函数的相关文章

C++:默认复制构造函数 执行 浅拷贝

C++, 会默认生成一个复制构造函数, 当类中出现指针时, 复制会执行浅拷贝, 即只复制指针的地址, 不会复制数据; 所以在类中, 使用指针时, 需要注意; 如果想使用深拷贝, 可以添加复制构造函数. 以下代码, 如果不添加复制构造函数, 则会运行出错, 但可以通过编译, 运行时, 因为删除(delete[])两次str所指的同一片地址空间, 所以程序无法执行. 代码: /* * main.cpp * * Created on: 2014.4.15 * Author: Spike */ /*vs

c++-关于复制构造函数跟赋值运算符重载

问题描述 关于复制构造函数跟赋值运算符重载 新手求指导 关于两个函数不太理解 复制构造的是同一个内存地址吗 为什么要重载赋值运算符 解决方案 赋值运算符和复制构造函数都是用已存在的B对象来创建另一个对象A.不同之处在于:赋值运算符处理两个已有对象,即赋值前B应该是存在的:复制构造函数是生成一个全新的对象,即调用复制构造函数之前A不存在. CTemp a(b); //复制构造函数,C++风格的初始化 CTemp a=b; //仍然是复制构造函数,不过这种风格只是为了与C兼容,与上面的效果一样 在这

何时需要自定义复制构造函数?

本文涉及对象的赋值和复制(也称为克隆).必要时,先看谭浩强教材P291-295的相关内容或PPT,重温一下有关概念. 一.一般情况 先看一个例子: //例程1 #include <iostream> using namespace std; class Complex { public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} friend Complex operator+(const Comp

c++-C++复制构造函数、内存共享

问题描述 C++复制构造函数.内存共享 通过复制构造函数,复制的对象与原对象共享内存么,求各位给个解释 解决方案 因为你的Pstu(const Pstu& p)这个拷贝函数里有这么一句pointer = p.pointer; 这就使得无论是p1还是p2他们的private成员变量pointer都指向了和p一样的内存地址 所以不管是哪个对象对自己的pointer所指向的对象的count执行++操作,三个对象都能看到 解决方案二: 很多时候在我们都不知道拷贝构造函数的情况下,传递对象给函数参数或者函

c++ 类 复制构造函数,析构函数

问题描述 c++ 类 复制构造函数,析构函数 c++类, 复制构造函数中产生的对象在程序结束后或运行中 会不会被析构 解决方案 只要程序正常运行,正常关闭,都会执行析构函数.如果你有疑问,你可以自己试验下. 解决方案二: 贴出你完整的代码 析构函数对于每个对象的实例只调用一次. 解决方案三: 1.如果没有显示定义复制构造函数或赋值操作符,编译器通常会为我们定义. 2.复制构造函数.赋值操作符.析构函数总称复制控制.编译器自动实现这些操作,蛋类也可以定义自己的版本. 3.有一种特别常见的情况需要类

BUG现形记(二)——偷工减料的复制构造函数

[课程支撑]我的 C++程序设计课程教学材料 [摘要]设计数组类,要实现数组类中两个数组相加的运算,程序却陷入死循环.逐层排查,重载的加法正确,重载的赋值运算也看不出问题.跟踪到赋值运算的实现中发现,传递的参数中有异常,终于找出了嫌疑犯--编制的复制构造函数偷工减料. [阅读提示]现在打开你熟悉的c++,跟随作者的的思路,重走发现嫌犯的过程. 题目是建立专门的数组类处理有关数组的操作,要完成支持数组操作的类的设计,增强C++内置数组类型功能.--见:第14周-任务1-数组类的构造 有同学向我求助

《C++面向对象高效编程(第2版)》——3.3 复制构造函数

3.3 复制构造函数 C++面向对象高效编程(第2版)③ TIntStack s2 = s1;这是一个小小的技巧.我们试图创建TIntStack类的另一个对象s2.但是,我们希望用s1初始化这个对象.换句话说,必须通过s1创建s2.当然,前提是s1已经存在.这类似于以下声明: int j; int k = j; // 创建一个k并初始化为j``` 在这种情况下,编译器知道如何用j初始化k,因为int是语言定义(内置)类型.然而,③中的TIntStack是程序员定义类型,这表明由程序员负责将s1初

复制构造函数 与 赋值函数 的区别

构造函数.析构函数.赋值函数是每个类最基本的的函数.每个类只有一个析构函数和一个赋值函数.但是有很多构造函数(一个为复制构造函数,其他为普通构造函数.对于一个类A,如果不编写上述四个函数,c++编译器将自动为A产生四个默认的函数,即: A(void)                                    //默认无参数构造函数 A(const A &a)                         //默认复制构造函数 ~A(void);                   

对象的初始化-用函数的返回值初始化一个类对象,这其中用了几次复制构造函数

问题描述 用函数的返回值初始化一个类对象,这其中用了几次复制构造函数 这是我自己写的一段代码#includeusing namespace std;class Example{int num;public:Example(int i){num=i;cout<<""This is construction with parameter.n"";}Example(){num=0;cout<<""This is construc