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

网站建设到上线的步骤过程优化大师优化项目有

网站建设到上线的步骤过程,优化大师优化项目有,上海做网站好的公司有哪些,免费微信小程序模板目录 拷贝构造函数一、为什么用拷贝构造二、拷贝构造函数1、概念2、特征1. 拷贝构造函数是构造函数的一个重载形式。2. 拷贝构造函数的参数3. 若未显式定义,编译器会生成默认的拷贝构造函数。4. 拷贝构造函数典型调用场景 拷贝构造函数 一、为什么用拷贝构造 日期…

目录

  • 拷贝构造函数
    • 一、为什么用拷贝构造
    • 二、拷贝构造函数
      • 1、概念
      • 2、特征
        • 1. 拷贝构造函数是构造函数的一个重载形式。
        • 2. 拷贝构造函数的参数
        • 3. 若未显式定义,编译器会生成默认的拷贝构造函数。
        • 4. 拷贝构造函数典型调用场景

拷贝构造函数

一、为什么用拷贝构造

日期类传值(这里是浅拷贝)

#include<iostream>
using namespace std;
class Date {
public:Date(int year=1, int month=1, int day=1) {_year = year;_month = month;_day = day;}void Print() {cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year ;int _month ;int _day ;
};
int main() {Date d1;d1.Print();return 0;
}

运行后:
在这里插入图片描述

这里进行了传值的拷贝,形参传给实参,进行了值拷贝,也就是浅拷贝,所以并没有出现问题。

但是栈类的结构浅拷贝会出现问题

#include<iostream>
using namespace std;class Stack{public:Stack(size_t capacity = 3){cout << "Stack(size_t capacity = 3)" << endl;_a = (int*)malloc(sizeof(int) * capacity);if (nullptr == _a){perror("malloc申请空间失败!!!");}_capacity = capacity;_top = 0;}~Stack(){cout << "~Stack()" << endl;free(_a);_capacity = _top = 0;_a = nullptr;}private:int* _a;int _capacity;int _top;};
int main() {Stack st1;Stack st2(st1);return 0;
}

运行后会变成
在这里插入图片描述
从上面我们可以看出程序崩溃了,这是为什么呢?
原因在于我们的栈的结构体类型中有一个指针来指向下一个结构体,当我们进行浅拷贝的时候会将这个地址也拷贝过去,但是我们的c++会自动调用析构函数,那么析构函数就被调用了两次,从上面的图中我们也可以看出来析构函数被调用了两次,所以程序崩溃了。

那么如何解决这个问题呢,我们的C++祖师爷,就定义了一个拷贝构造函数 来解决这个问题。

二、拷贝构造函数

1、概念

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

2、特征

拷贝构造函数也是特殊的成员函数,其特征如下:

1. 拷贝构造函数是构造函数的一个重载形式。
2. 拷贝构造函数的参数

拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用

下面写一个拷贝构造函数重新进行运行:

#include<iostream>
using namespace std;class Stack{public:Stack(size_t capacity = 3){cout << "Stack(size_t capacity = 3)" << endl;_a = (int*)malloc(sizeof(int) * capacity);//要重新开辟空间if (nullptr == _a){perror("malloc申请空间失败!!!");}_capacity = capacity;_top = 0;}//拷贝构造函数Stack(const Stack& stt ) {_a = (int*)malloc(sizeof(int) * stt._capacity);if (_a == nullptr) {perror("malloc");exit(-1);}memcpy(_a, stt._a, sizeof(int) * stt._top);_capacity = stt._capacity;_top = stt._top;}~Stack(){cout << "~Stack()" << endl;free(_a);_capacity = _top = 0;_a = nullptr;}private:int* _a;int _capacity;int _top;};
void Func(Stack stt) {//....
}
int main() {Stack st1;Func(st1);return 0;
}

就会发现是正常运行,如下在这里插入图片描述

		//拷贝构造函数Stack(const Stack& stt ) {_a = (int*)malloc(sizeof(int) * stt._capacity);if (_a == nullptr) {perror("malloc");exit(-1);}memcpy(_a, stt._a, sizeof(int) * stt._top);_capacity = stt._capacity;_top = stt._top;}

通过拷贝构造函数我们可以看出,是重新开辟了一块空间进行拷贝构造,而且我们使用了引用(&)。那么为什么要用引用呢?
下面我们用日期类函数进行演示:

#include<iostream>
using namespace std;
class Date {
public:Date(int year=1, int month=1, int day=1) {_year = year;_month = month;_day = day;}//错误的拷贝构造函数Date(Date d) {_year = d._year;_month = d._month;_day = d._day;}void Print() {cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year ;int _month ;int _day ;
};
int main() {Date d1;d1.Print();Date d2(d1);d2.Print();return 0;
}

我们会发现代码没有办法运行,进行下面的报错
在这里插入图片描述
这是由于当我们d2要对d1进行拷贝构造时发生了以下过程:
规定传值传参都要去调用拷贝构造函数那么,中间就还有临时变量要创建和拷贝,这样一环套一环没有终点。如下:
在这里插入图片描述
综上,所以我们要用引用,直接将d1赋值给d,如下所示:
在这里插入图片描述

#include<iostream>
using namespace std;
class Date {
public:Date(int year=1, int month=1, int day=1) {_year = year;_month = month;_day = day;}//正确的拷贝构造函数Date(Date& d) {_year = d._year;_month = d._month;_day = d._day;}void Print() {cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year ;int _month ;int _day ;
};
int main() {Date d1;d1.Print();Date d2(d1);d2.Print();return 0;
}
3. 若未显式定义,编译器会生成默认的拷贝构造函数。

默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。

所以其实日期类是不用进行我们自己写拷贝构造函数的,因为日期类浅拷贝就够用了,我在上面用日期类进行举例是为了方便我们理解。拷贝构造还是主要用在我开始写的栈类型的程序上。

#include<iostream>
using namespace std;class Stack{public:Stack(size_t capacity = 3){cout << "Stack(size_t capacity = 3)" << endl;_a = (int*)malloc(sizeof(int) * capacity);//要重新开辟空间if (nullptr == _a){perror("malloc申请空间失败!!!");}_capacity = capacity;_top = 0;}//拷贝构造函数Stack(const Stack& stt ) {_a = (int*)malloc(sizeof(int) * stt._capacity);if (_a == nullptr) {perror("malloc");exit(-1);}memcpy(_a, stt._a, sizeof(int) * stt._top);_capacity = stt._capacity;_top = stt._top;}~Stack(){cout << "~Stack()" << endl;free(_a);_capacity = _top = 0;_a = nullptr;}private:int* _a;int _capacity;int _top;};
void Func(Stack stt) {//....
}
int main() {Stack st1;Func(st1);Stack st2(st1);return 0;
}

通过调试上述代码我们发现,它们_a的地址不同,但是_capacity、_top的值是相同的,成功完成了拷贝构造。
在这里插入图片描述
运行后的结果如下:
在这里插入图片描述

4. 拷贝构造函数典型调用场景

使用已存在对象创建新对象
函数参数类型为类类型对象
函数返回值类型为类类型对象

http://www.tj-hxxt.cn/news/69066.html

相关文章:

  • dw怎么做滚动视差的网站网店代运营骗局流程
  • 公益网站怎么做友链提交入口
  • 自己做的网站打开是乱码宁波seo推荐推广平台
  • 东莞网约车资格证官网登录入口百度关键词优化公司
  • 个人网站设计摘要域名查询ip138
  • 做钢材生意一般做什么网站好长沙网站外包公司
  • 临沂网站建设方案书百度推广
  • 建设通官网通seo在哪可以学
  • html5官网免费下载搜索引擎优化
  • 学校内部网站开发价格推广业务
  • 仿牌外贸网站建设静态网站开发
  • 网站用户维度汉川seo推广
  • 白银网站建设熊掌号网站推广的公司
  • 网站如何布局什么是网站seo
  • 免费的二维码生成软件湖州网站seo
  • 网站开发课程培训爱站网站长百度查询权重
  • 常州企业免费建站短期的技能培训有哪些
  • 优秀的国内企业网站站长之家seo综合查询
  • 网站开发目录规范邢台市seo服务
  • 营销型网站建设易网拓百度明令禁止搜索的词
  • 好公司网站建设价格青岛关键词网站排名
  • 做网站横幅技巧绍兴seo网站推广
  • 做一个平台网站要多少钱百度seo怎么提高排名
  • 网络推广网站优化推广什么意思
  • 网站建设个人网站湖北seo
  • 如何提高网站的曝光率百度网站关键词排名助手
  • 阿里巴巴 商城网站怎么做企业网站有哪些功能
  • psd做成网站网页设计
  • 学校网站模板下载百度竞价sem入门教程
  • 做网站可以用哪些语言用广州seo推广获精准访问量