当前位置: 首页 > news >正文

C++:复制构造函数在什么时候被调用?

1、对象在创建时使用其他的对象初始化

Person p(q); //此时复制构造函数被用来创建实例p

Person p = q; //此时复制构造函数被用来在定义实例p时初始化p

2、对象作为函数的参数进行值传递时

f(p); //此时p作为函数的参数进行值传递,p入栈时会调用复制构造函数创建一个局部对象,与函数内的局部变量具有相同的作用域

需要注意的是,赋值并不会调用复制构造函数,赋值只是赋值运算符(重载)在起作用

p = q; //此时没有复制构造函数的调用!

简单来记的话就是,如果对象在声明的同时将另一个已存在的对象赋给它,就会调用复制构造函数;如果对象已经存在,然后将另一个已存在的对象赋给它,调用的就是赋值运算符(重载)

默认的复制构造函数和赋值运算符进行的都是"shallow copy",只是简单地复制字段,因此如果对象中含有动态分配的内存,就需要我们自己重写复制构造函数或者重载赋值运算符来实现"deep copy",确保数据的完整性和安全性。

eg:

string.h

#include<iostream>
#include<cstring>
#ifndef STRING_H_
#define STRING_H_
class string
{
private:
    char *data;
public:
    string();
    string(const char *value);
    string(const string & s);
    ~string();
    operator=(const string & s);
};
#endif

string_h.cpp

#include"string.h"
using std::cout;
using std::endl;

string::string()
{
    data=new char[4];
    data="c++";
   cout<<"構造函數無參:"<<data<<endl;
}
string::string(const char *value) { if(value) { data=new char[strlen(value)+1]; strcpy(data,value); } else { data=new char[1]; *data='\0'; } cout<<"構造函數有參:"<<data<<endl; } string::string(const string & s) { data=new char[strlen(s.data)+1]; strcpy(data,s.data); cout<<"複製構造函數:"<<data<<endl; } string::~string() { delete [] data; } string::operator =(const string & s) { data=new char[strlen(s.data)+1]; strcpy(data,s.data); cout<<"重載操作符=:"<<data<<endl; }

string.cpp

#include<iostream>
#include"string.h"

int main()
{
    string a("hello"); // 定義並構造 a ,有參構造
    string b(a); // 定義並構造b,顯式調用複製構造函數
    string c;//無參構造 
    c=a;//調用操作符重載
    string d=c;//隱式調用複製構造函數,而不是操作符重載
    return 0;
}

相关文章:

  • js模拟hashtable
  • 取消锚(a/)点击后页面跳转的几种方法
  • 程序员面试题100题第26题——和为n连续正数序列
  • 软考 (一) 感触
  • 第二十三模板 15模板和友元
  • Android之loader
  • 第六天之还得接着采集
  • Emacs的haskell-mode的安装
  • 网络时间协议 --- 网络对时程序
  • Cocoa、Foundation、UIKit的概念
  • 想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下?...
  • 浏览器是怎样工作的:渲染引擎,HTML解析(连载二)
  • NoSQL数据库大全收集整理
  • Android对象封装及按汉语拼音排序
  • 虚拟目录
  • 【译】JS基础算法脚本:字符串结尾
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • HTTP--网络协议分层,http历史(二)
  • idea + plantuml 画流程图
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JAVA之继承和多态
  • MySQL QA
  • Python十分钟制作属于你自己的个性logo
  • QQ浏览器x5内核的兼容性问题
  • 阿里云前端周刊 - 第 26 期
  • 从输入URL到页面加载发生了什么
  • 全栈开发——Linux
  • 深入 Nginx 之配置篇
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 学习JavaScript数据结构与算法 — 树
  • 怎样选择前端框架
  • 智能网联汽车信息安全
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • puppet连载22:define用法
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (C语言)二分查找 超详细
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (理论篇)httpmoudle和httphandler一览
  • (十六)串口UART
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET框架
  • /dev/sda2 is mounted; will not make a filesystem here!
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [20160807][系统设计的三次迭代]
  • [c#基础]DataTable的Select方法
  • [CC2642R1][VSCODE+Embedded IDE+IAR Build+Cortex-Debug] TI CC2642R1基于VsCode的开发环境