返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++中的拷贝构造函数怎么用
  • 173
分享到

C++中的拷贝构造函数怎么用

2023-06-29 04:06:08 173人浏览 独家记忆
摘要

小编给大家分享一下c++中的拷贝构造函数怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C++拷贝构造函数(复制构造函数)详解拷贝和复制是一个意思,对应的英文

小编给大家分享一下c++中的拷贝构造函数怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

    C++拷贝构造函数(复制构造函数)详解

    拷贝和复制是一个意思,对应的英文单词都是copy。对于计算机来说,拷贝是指用一份原有的、已经存在的数据创建出一份新的数据,最终的结果是多了一份相同的数据。例如,将 Word 文档拷贝到U盘去复印店打印,将 D 盘的图片拷贝到桌面以方便浏览,将重要的文件上传到百度网盘以防止丢失等,都是「创建一份新数据」的意思。

    在 C++ 中,拷贝并没有脱离它本来的含义,只是将这个含义进行了“特化”,是指用已经存在的对象创建出一个新的对象。从本质上讲,对象也是一份数据,因为它会占用内存。

    严格来说,对象的创建包括两个阶段,首先要分配内存空间,然后再进行初始化:

    分配内存很好理解,就是在堆区、栈区或者全局数据区留出足够多的字节。这个时候的内存还比较“原始”,没有被“教化”,它所包含的数据一般是零值或者随机值,没有实际的意义。

    初始化就是首次对内存赋值,让它的数据有意义。注意是首次赋值,再次赋值不叫初始化。初始化的时候还可以为对象分配其他的资源(打开文件、连接网络、动态分配内存等),或者提前进行一些计算(根据价格和数量计算出总价、根据长度和宽度计算出矩形的面积等)等。说白了,初始化就是调用构造函数。

    很明显,这里所说的拷贝是在初始化阶段进行的,也就是用其它对象的数据来初始化新对象的内存。

    那么,如何用拷贝的方式来初始化一个对象呢?其实这样的例子比比皆是,string 类就是一个典型的例子。

    #include <iOStream>#include <string>using namespace std;void func(string str){    cout<<str<<endl;}int main(){    string s1 = "Http://c.ttt.net";    string s2(s1);    string s3 = s1;    string s4 = s1 + " " + s2;    func(s1);    cout<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl;       return 0;}运行结果:http://c.ttt.nethttp://c.ttt.nethttp://c.ttt.nethttp://c.ttt.nethttp://c.ttt.net http://c.ttt.net

    s1、s2、s3、s4 以及 func() 的形参 str,都是使用拷贝的方式来初始化的。
    对于 s1,表面上看起来是将一个字符串直接赋值给了 s1,实际上在内部进行了类型转换,将 const char * 类型转换为 string 类型后才赋值的。s4 也是类似的道理。

    对于 s1、s2、s3、s4,都是将其它对象的数据拷贝给当前对象,以完成当前对象的初始化。

    对于 func() 的形参 str,其实在定义时就为它分配了内存,但是此时并没有初始化,只有等到调用 func() 时,才会将其它对象的数据拷贝给 str 以完成初始化。

    当以拷贝的方式初始化一个对象时,会调用一个特殊的构造函数,就是拷贝构造函数(Copy Constructor)。

    下面的例子演示了拷贝构造函数的定义和使用:

    #include <iostream>#include <string>using namespace std;class Student{public:    Student(string name = "", int age = 0, float score = 0.0f);  //普通构造函数    Student(const Student &stu);  //拷贝构造函数(声明)public:    void display();private:    string m_name;    int m_age;    float m_score;};Student::Student(string name, int age, float score): m_name(name), m_age(age), m_score(score){ }//拷贝构造函数(定义)Student::Student(const Student &stu){    this->m_name = stu.m_name;    this->m_age = stu.m_age;    this->m_score = stu.m_score;       cout<<"Copy constructor was called."<<endl;}void Student::display(){    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;}int main(){    Student stu1("小明", 16, 90.5);    Student stu2 = stu1;  //调用拷贝构造函数    Student stu3(stu1);  //调用拷贝构造函数    stu1.display();    stu2.display();    stu3.display();       return 0;}

    运行结果:

    Copy constructor was called.
    Copy constructor was called.
    小明的年龄是16,成绩是90.5
    小明的年龄是16,成绩是90.5
    小明的年龄是16,成绩是90.5

    第 8 行是拷贝构造函数的声明,第 20 行是拷贝构造函数的定义。拷贝构造函数只有一个参数,它的类型是当前类的引用,而且一般都是 const 引用。

    1) 为什么必须是当前类的引用呢?

    如果拷贝构造函数的参数不是当前类的引用,而是当前类的对象,那么在调用拷贝构造函数时,会将另外一个对象直接传递给形参,这本身就是一次拷贝,会再次调用拷贝构造函数,然后又将一个对象直接传递给了形参,将继续调用拷贝构造函数&hellip;&hellip;这个过程会一直持续下去,没有尽头,陷入死循环。

    只有当参数是当前类的引用时,才不会导致再次调用拷贝构造函数,这不仅是逻辑上的要求,也是 C++ 语法的要求。

    2) 为什么是 const 引用呢?

    拷贝构造函数的目的是用其它对象的数据来初始化当前对象,并没有期望更改其它对象的数据,添加 const 限制后,这个含义更加明确了。

    另外一个原因是,添加 const 限制后,可以将 const 对象和非 const 对象传递给形参了,因为非 const 类型可以转换为 const 类型。如果没有 const 限制,就不能将 const 对象传递给形参,因为 const 类型不能转换为非 const 类型,这就意味着,不能使用 const 对象来初始化当前对象了。

    以上面的 Student 类为例,将 const 去掉后,拷贝构造函数的原型变为:
    Student::Student(Student &stu);

    此时,下面的代码就会发生错误:

    const Student stu1("小明", 16, 90.5);Student stu2 = stu1;Student stu3(stu1);

    stu1 是 const 类型,在初始化 stu2、stu3 时,编译器希望调用Student::Student(const Student &stu),但是这个函数却不存在,又不能将 const Student 类型转换为 Student 类型去调用Student::Student(Student &stu),所以最终调用失败了。

    当然,你也可以再添加一个参数为 const 引用的拷贝构造函数,这样就不会出错了。换句话说,一个类可以同时存在两个拷贝构造函数,一个函数的参数为 const 引用,另一个函数的参数为非 const 引用。

    默认拷贝构造函数

    在前面的教程中,我们还没有讲解拷贝构造函数,但是却已经在使用拷贝的方式创建对象了,并且也没有引发什么错误。这是因为,如果程序员没有显式地定义拷贝构造函数,那么编译器会自动生成一个默认的拷贝构造函数。这个默认的拷贝构造函数很简单,就是使用“老对象”的成员变量对“新对象”的成员变量进行一一赋值,和上面 Student 类的拷贝构造函数非常类似。

    对于简单的类,默认拷贝构造函数一般是够用的,我们也没有必要再显式地定义一个功能类似的拷贝构造函数。但是当类持有其它资源时,如动态分配的内存、打开的文件、指向其他数据的指针、网络连接等,默认拷贝构造函数就不能拷贝这些资源,我们必须显式地定义拷贝构造函数,以完整地拷贝对象的所有数据。

    以上是“C++中的拷贝构造函数怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网其他教程频道!

    --结束END--

    本文标题: C++中的拷贝构造函数怎么用

    本文链接: https://lsjlt.com/news/322432.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • C++中的拷贝构造函数怎么用
      小编给大家分享一下C++中的拷贝构造函数怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C++拷贝构造函数(复制构造函数)详解拷贝和复制是一个意思,对应的英文...
      99+
      2023-06-29
    • C++拷贝构造函数怎么使用
      本文小编为大家详细介绍“C++拷贝构造函数怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++拷贝构造函数怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。构造函数只有单个形参,该形参是对本类类型对...
      99+
      2023-06-30
    • C++中拷贝构造函数的使用
      目录拷贝构造函数1. 手动定义的拷贝构造函数2. 合成的拷贝构造函数总结拷贝构造函数 拷贝构造函数,它只有一个参数,参数类型是本类的引用。复制构造函数的参数可以是 const 引用,...
      99+
      2024-04-02
    • c++中拷贝构造函数的作用
      c++ 中拷贝构造函数的作用:确保创建对象副本,与原始对象完全独立。保护原始对象不受修改,即使传递给函数的对象被修改。创建对象副本以用于不同目的,而不会影响原始对象。 C++ 中拷贝构...
      99+
      2024-05-12
      c++
    • C++中的拷贝构造函数详解
      目录C++拷贝构造函数(复制构造函数)详解1) 为什么必须是当前类的引用呢?2) 为什么是 const 引用呢?默认拷贝构造函数总结C++拷贝构造函数(复制构造函数)详解 拷贝和复制...
      99+
      2024-04-02
    • C++拷贝构造函数中的陷阱
      转自微信公众号:CPP开发前沿 拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象,拷贝一份副本。不过看似简单的东西,实际不注意的话就会产生问题! #include<iostr...
      99+
      2024-04-02
    • C++拷贝构造函数(深拷贝与浅拷贝)详解
      对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝...
      99+
      2022-11-15
      拷贝构造函数 深拷贝 浅拷贝
    • C++的拷贝构造函数是什么
      这篇文章主要介绍了C++的拷贝构造函数是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。拷贝构造函数用以将一个类的对象拷贝给同一个类的另一个对象,比如之前学习过的strin...
      99+
      2023-06-29
    • C++中类对象的拷贝构造函数
      本篇内容主要讲解“C++中类对象的拷贝构造函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++中类对象的拷贝构造函数”吧!拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一...
      99+
      2023-06-17
    • C++拷贝构造函数中的陷阱怎么解决
      这篇文章主要讲解了“C++拷贝构造函数中的陷阱怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++拷贝构造函数中的陷阱怎么解决”吧!拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象...
      99+
      2023-06-26
    • C++修炼之拷贝构造函数
      目录💐文章导读🌷拷贝构造函数的概念🌷拷贝构造函数的特性💐文章导读 本章主要内容为6个默认成员函数之一的拷贝构造函数的认识与学习,充分理解浅拷贝与深拷贝。 🌷拷贝构造函数的概念 还记得...
      99+
      2023-05-14
      C++拷贝构造函数 C++构造函数 拷贝构造函数
    • C++中拷贝构造函数的总结详解
      1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了。(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数。百度百科上是这...
      99+
      2022-11-15
      拷贝构造函数 C++
    • C++构造函数的类型,浅拷贝与深拷贝详解
      目录一、无参构造函数二、含参构造函数三、拷贝构造函数四、深拷贝和浅拷贝总结一、无参构造函数 1.如果没有定义构造函数,则系统自动调用此默认构造函数,且什么都不做。 2.如果用户自定义...
      99+
      2024-04-02
    • C++的拷贝构造函数你了解吗
      目录一般情况下的拷贝构造函数:默认拷贝构造函数:浅拷贝和深拷贝:总结拷贝构造函数用以将一个类的对象拷贝给同一个类的另一个对象,比如之前学习过的string类: string s1; ...
      99+
      2024-04-02
    • C++中的拷贝构造详解
      目录拷贝构造函数拷贝构造中的引用什么情况会使用拷贝构造总结拷贝构造函数 同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完美可行的,这个拷贝过程只需要拷贝数...
      99+
      2024-04-02
    • C++中的拷贝构造是怎样的
      这期内容当中小编将会给大家带来有关C++中的拷贝构造是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。拷贝构造函数同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完美可行的,...
      99+
      2023-06-26
    • C++超详细讲解拷贝构造函数
      目录构造函数特征编译器生成的拷贝构造拷贝构造的初始化列表显式定义拷贝构造的误区结论构造函数 只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对...
      99+
      2024-04-02
    • C++构造函数的类型,浅拷贝与深拷贝实例分析
      本文小编为大家详细介绍“C++构造函数的类型,浅拷贝与深拷贝实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++构造函数的类型,浅拷贝与深拷贝实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、无...
      99+
      2023-06-29
    • c++详细讲解构造函数的拷贝流程
      #include <iostream> #include <string> using namespace std; void func(string str...
      99+
      2024-04-02
    • C++实现拷贝构造函数的方法详解
      目录引入一.什么是拷贝构造函数二.什么情况下使用拷贝构造函数三.使用拷贝构造函数需要注意什么四.深拷贝浅拷贝4.1 浅拷贝4.2 深拷贝引入 对于普通类型的对象来说,他们之间的复制很...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作