C++(18)--复制构造函数

复制构造函数


《老九学堂C++课程》《C++ primer》学习笔记。《老九学堂C++课程》详情请到B站搜索《老九零基础学编程C++入门》
-------------简单的事情重复做,重复的事情用心做,用心的事情坚持做(老九君)---------------

包装基本类,封装一些算法。
需求说明:自定义String类,以简化字符串的操作。

//main.cpp
#include <iostream>
#include "MyString.h"
using namespace std;
void TestString(){String str1("abc");//String str2="abcdefg";   // 寻找带char * 参数的构造--转换构造String str2(str1);         // 如此指向同一个内存空间,需要复制构造函数cout << str1 << endl;cout << str2 << endl;cout << "对象之间的赋值"<< endl;str1 = str2;    // 指向同一个地址,需要重载= 预算符// 为啥他把地址也给打出来了cout << str1 << endl;cout << str2 << endl;
}
int main() {//TestIntefer();TestString();return 0;
}
//MyString.h
//
// Created by 陈莹莹 on 2021/3/4.
// 自定义的字符串包装类#ifndef CHAPTER12_MYSTRING_H
#define CHAPTER12_MYSTRING_H
#include <iostream>
#include <cstring>using namespace std;class String {
public:String();String(char * str);String(const String & str); // 参数是引用,所以是复制构造/拷贝构造~String();friend ostream & operator<<(ostream & out, const String & str);// 重载复制运算符,将数组中的每个元素都进行复制,而不是只复制数组指针const String & operator=(const String & str);
private:int m_length;   // 字符串的实际长度-不包括\0char * m_value;  // 实际存储字符的字符数组,指针好用};#endif //CHAPTER12_MYSTRING_H
//MyString.cpp
//
// Created by 陈莹莹 on 2021/3/4.
//#include "MyString.h"
String::String() :m_length(0)
{this->m_value = new char[m_length + 1];this->m_value[0] = '\0';// 等价于// char * str = ""; 长度为0,但实际的字符数组中会存在唯一元素:\0--结束符号
}
String::String(char * str) {if(NULL == str){this->m_value = new char[m_length + 1];this->m_value[0] = '\0';return;}// 将传入的字符串str的值赋给当前对象中的m_valuem_length = strlen(str); // 要复制字符串的长度m_value = new char[m_length + 1];strcpy(m_value, str);
}
String::String(const String & str){// 重载复制运算符,就一定要拷贝构造m_length= str.m_length;m_value = new char[m_length + 1];strcpy(m_value, str.m_value);
}
ostream & operator<<(ostream & out, const String & str)
{out << str.m_value<<"\n";// out <<  "m_value的长度:" << strlen(str.m_value);out <<  "m_value的长度:" << str.m_length;return out;
}
// 当重载赋值运算符,务必确定将一个对象中的所有数据都复制到另一对象中(特别是有指针时)
// 如果包含多个成员,那么每个成员都需要复制到内存对象中-深复制
// 如果一个类拥有指针类型的成员,那么大部分情况下都需要深赋值,才能将指针指向的内容复制一份出来,让原来的额对象和新对象相互独立
// 如果类的成员没有指针,一般浅赋值即可
const String & String::operator=(const String & str){if(this == &str) return *this;delete[] m_value; // 首先要释放字符串原始空间m_length = str.m_length;m_value = new char[m_length + 1];strcpy(m_value, str.m_value);return *this;
}
String::~String()
{// 析构时,释放字符数组所指向的空间delete[] m_value;
}

情况1:不重载运算符,对象str1的内容直接复制到新对象str2中,对于没有指针的简单类来说,这就足够了。当成员包含指针时,逐字节的复制将会把指针从一个对象复制给另一个对象,两个指针就指向同一个内存
解决方案:重载赋值运算符号

String str1 = "爱吃新红柿";
String str2;
str2 = str1;

情况2:使用一个类对象去初始化另一个对象,也会出现两个指针指向同一块内存地址的问题。
解决方案:复制构造函数(以对象为引用为参数的构造函数)

xxx::xxx(xxx & xxxptr);
xxx::xxx(const xxx & xxxptr); // const 保证复制过程中不会改变被复制对象

String str1("爱吃新红柿");
String str2(str1);
str2 = str1;

需要使用复制构造函数的三种情况

  1. 当类对象被初始化为同一类的另一个对象时
  2. 当对象被作为参数传递给一个函数时
  3. 当函数返回一个对象时
String str = "abc";
test(str); // 按副本传递,默认调用复制构造,如果没有实现复制构造的话,会调用浅复制(指向同一块内存地址)
viod test(String str){}
String test(String str){	String str1 = "abc";return str1;  // 需要写复制构造函数
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lua与C++粘合层框架

一. lua调用C 在lua中是以函数指针的形式调用函数, 并且所有的函数指针都必须满足如下此种类型: typedef int (*lua_CFunction) (lua_State *L);   也就是说, 偶们在C中定义函数时必须以lua_State为参数, 以int为返回值才能被Lua所调用. 但是不要忘记了, 偶们的lua_State是…

leetcode147 对链表进行插入排序

丢人&#xff0c;我就是按插入排序老老实实写的啊。。。。 别人肯定map了hhh。 对链表进行插入排序。 插入排序的动画演示如上。从第一个元素开始&#xff0c;该链表可以被认为已经部分排序&#xff08;用黑色表示&#xff09;。 每次迭代时&#xff0c;从输入数据中移除一个…

PaperNotes(13)-Conditional Image Generation with PixelCNN Decoders

conditional Image generation with PixelCNN DecodersICML的best paperpixel cnn 属于完全可见的信念网络&#xff0c;需要对 概率密度 建模。给定图像数据x&#xff0c;想要对概率分布p(x)建模。概率分布p(x)可以看做&#xff0c;每一像素分布同时作用结果的一个联合分布。一…

Expression : invalid operator 解决方法

从技术上说&#xff0c;用于排序关联容器的比较函数必须在它们所比较的对象上定义一个“严格的弱序化(strict weak ordering)”。&#xff08;传给sort等算法的比较函数也有同样的限制&#xff09;,就是两个对象比大小或先后的规则&#xff0c;比如两个 string对象比大小的规则…

leetcode23 合并K个排序链表

合并 k 个排序链表&#xff0c;返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 思路&#xff1a;把初始的每一个链表当成数组中的一个数&#xff0c;做…

Xcode LaunchImage 载入界面大小设置

iPhone Portrait iOS 8-Retina HD 5.5 (12422208) @3x iPhone Portrait iOS 8-Retina HD 4.7 (7501334) @2x iPhone Portrait iOS 7,8-2x (640960) @2x iPhone Portrait iOS 7,8-Retina 4 (6401136) @2x iPhone Portrait iOS 5,6-1x (320480) @1x iPhone Portrait iO…

leetcode237 删除链表中的节点(你意想不到的做法,注意细节)

请编写一个函数&#xff0c;使其可以删除某个链表中给定的&#xff08;非末尾&#xff09;节点&#xff0c;你将只被给定要求被删除的节点。 现有一个链表 -- head [4,5,1,9]&#xff0c;它可以表示为: 示例 1: 输入: head [4,5,1,9], node 5 输出: [4,1,9] 解释: 给定你链…

cppcheck值得注意的一些筛选项

使用完cppcheck进行C代码检测之后&#xff0c;可能筛选起来很麻烦&#xff0c;一般常见的优化有 emptiness&#xff0c;就是当你使用stl的时候&#xff0c;最好用empty替代size 还有就是 leak

C++(19)--自定义Array,vector练习

自定义Array,vector1.自定义Array2.自定义vector《老九学堂C课程》《C primer》学习笔记。《老九学堂C课程》详情请到B站搜索《老九零基础学编程C入门》-------------简单的事情重复做&#xff0c;重复的事情用心做&#xff0c;用心的事情坚持做(老九君)---------------1.自定义…

让cocos2dx支持并通过arm64 编译

为了要支持64位,请把这个文件直接替换到对应的lib目录下,本来是需要改neton_matrix_impl.c里的宏定义, 在 platform/ios/EAGLVIEW.mm中 在neon_matrix_impl.c中修改 #if defined(__ARM_NEON__) 为#if defined(_ARM_ARCH_7) 还有 third_party目录下的curl的支持。

springboot——概述

Spring Boot 介绍 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计⽬的是⽤来简化新 Spring 应⽤ 初始搭建以及开发过 程&#xff0c;该框架使⽤了特定的⽅式来进⾏配置&#xff0c;从⽽使开发⼈员不再需要定义样板化的配置。 默认配置了很多框架的使⽤⽅式…

C++(20)--类型自动转换

类型自动转换1.C内置类型转换2.实现自定义类的类型转换《老九学堂C课程》《C primer》学习笔记。《老九学堂C课程》详情请到B站搜索《老九零基础学编程C入门》 -------------简单的事情重复做&#xff0c;重复的事情用心做&#xff0c;用心的事情坚持做(老九君)---------------…

关于遍历linux的文件目录的坑- readdir

去年给公司写了一个配置服务器,目的是解决运维的工作量太大,而且传送服务器需要的配置文件需要脚本传送到各个服(每个服ip不一样,需要scp),然后再刷新通知各个GameServer,中间有没有传送失败并不得知,而且维护相当麻烦,所以我写了这个服务器,所有区服的配置都在这里边…

终于,我读懂了所有Java集合——sort

Collections.sort 事实上Collections.sort方法底层就是调用的Arrays.sort方法&#xff0c;而Arrays.sort使用了两种排序方法&#xff0c;快速排序和优化的归并排序。 快速排序主要是对那些基本类型数据&#xff08;int,short,long等&#xff09;排序&#xff0c; 而归并排序用于…

PRML(1)--绪论(上)多项式曲线拟合、概率论

PRML绪论1.1 多项式曲线拟合1.1.1 问题描述1.1.2 最小化平方和误差1.1.3 多项式阶数确定1.1.4 有趣问题--高阶模型为什么效果不好1.1.4 数据集规模对模型的影响1.1.5 参数正则化缓解过拟合问题1.2 概率论1.2.1离散型随机变量1.2.2 连续型随机变量1.2.3 期望和方差1.2.4 贝叶斯概…

大数加减乘

如标题&#xff0c;不解释。 加 #include<stdio.h> #include<string.h> int main() {char a[1000],b[1000];int i,s[1000],len1,len2,len,j;while(scanf("%s%s",a,b)!EOF) //用字符数组来储存数{for(i0;i<1000;i)s[i]0;len1strlen(a);len2strlen(b…

在GCC和Visual Studio中使用hash_map

熟悉STL或熟悉ACM/ICPC的话&#xff0c;其中的set, map, multiset, multimap一定用过无数次了&#xff0c;它们都是用平衡二叉树&#xff08;红黑树&#xff09;实现的&#xff0c;复杂度为O(lgn)。我们也知道set, map可以通过哈希来实现&#xff0c;复杂度只有O(1)&#xff0c…

C++(21)--Astah uml 画C++类图

Astah uml 画C类图1.安装2.使用《老九学堂C课程》《老九学堂C课程》详情请到B站搜索《老九零基础学编程C入门》-------------简单的事情重复做&#xff0c;重复的事情用心做&#xff0c;用心的事情坚持做(老九君)--------------- ASTAH&#xff1a;类图工具&#xff0c;用于理…

redis3.0.0 集群安装详细步骤

Redis集群部署文档(centos6系统) &#xff08;要让集群正常工作至少需要3个主节点&#xff0c;在这里我们要创建6个redis节点&#xff0c;其中三个为主节点&#xff0c;三个为从节点&#xff0c;对应的redis节点的ip和端口对应关系如下&#xff09; 127.0.0.1:7000 127.0.0.1:7…

Redis集群添加节点

Redis集群添加节点 1&#xff1a;首先把需要添加的节点启动 cd /usr/local/cluster/ mkdir 7006 cp /usr/local/cluster/redis.conf /usr/local/cluster/7006/ cd /usr/local/cluster/7006/ vi redis.conf ##修改redis.conf中的port参数的值为7006 redis-server redis.c…