C++之--拷贝(复制)构造函数

来源:互联网 发布:网络语言暴力的案例 编辑:程序博客网 时间:2024/06/05 06:13

C++之--拷贝(复制)构造函数

C++在类之中除了默认提供构造函数,同时还默认提供了拷贝构造函数又称复制构造函数。

如果在创建对象的时候要用同类对象来进行初始化,那么这个时候就要用到拷贝构造函数。

拷贝构造函数也是构造函数,不过是一种的特殊的构造函数罢了。

下面来看一下简单的代码:

#include <iostream>using namespace std;class  Student{public://全缺省构造参数Student(char* Name = "吴力", char* Sex = "男", int Age = 19){this->name = Name;this->sex = Sex;this->age = Age;}void showinfo(){cout << "name: " << name << endl;cout << "sex: " << sex << endl;cout << "age: " << age << endl;}private:int age;char* name;char* sex;};int main(){Student stu1;stu1.showinfo();//用stu1来初始化stu2对象Student stu2(stu1);stu2.showinfo();system("pause");return 0;}

image.png

程序运行结果无误,对象stu1初始化了stu2。

那么这是怎么实现的呢?其实这是调用了拷贝构造函数来完成的初始化。

#include <iostream>using namespace std;class  Student{public://全缺省构造参数Student(char* Name = "吴力", char* Sex = "男", int Age = 19){this->name = Name;this->sex = Sex;this->age = Age;}//拷贝构造函数Student(const Student & _stdt){cout << endl << "这是拷贝构造函数的测试" << endl;name = _stdt.name;sex = _stdt.sex;age = _stdt.age;}void showinfo(){cout << "name: " << name << endl;cout << "sex: " << sex << endl;cout << "age: " << age << endl;}private:int age;char* name;char* sex;};int main(){Student stu1;stu1.showinfo();//用stu1来初始化stu2对象Student stu2(stu1);stu2.showinfo();system("pause");return 0;}

上面的代码中,显现的实现了拷贝构造函数,程序运行结果如下:
image.png这段代码中拷贝构造函数是人为定义的,大家可以通过运行结果清楚的看到,拷贝构造函数在用stu1初始化stu2的时候进行了调用。

而拷贝构造函数与构造函数的不同是在于参数的不同,拷贝构造函数传参是一个已经在存在的对象的引用,而构造函数则是普通的成员变量的传参。

传参的时候加上const修饰,能够提高程序的安全性,鲁棒性,防止意外在函数内部将_stdt进行了改变,影响了结果

那么为什么拷贝构造函数在传参的时候要传对象的引用而不传对象呢?

image.png

我们可以发现,当传参的时候,不进行引用的传参,而进行 对象的直接传递,编译器会直接报错。我们可以分析一下:

直接用对象进行传参的时候,首先会在栈帧中开辟新空间存放建立的临时变量,来将实参的内容拷贝进去,而建立了临时变量,在将实参的内容(即对象的内容)拷贝过程中,又要再一次的调用拷贝构造函数,这样的话,会陷入无穷递归当中。所以编译器在检查的时候,直接认定以对象来传参是错误的。

而在平常我们调用拷贝构造函数,可以用以下两种方式都行:

image.png

需要注意的是,拷贝构造函数若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会依次拷贝类成员进行初始化。不过默认的拷贝构造函数只是进行了“浅拷贝,一般的情况没有问题,但是,如果类里面存在动态开辟的空间,只依靠系统默认的拷贝构造函数的话,则会出现问题,因为浅拷贝会拷贝的是已经析构的空间。具体的内容,我会在之后写一篇博客专门来剖析一下“深浅拷贝”,这里就不多做阐述。


原创粉丝点击