C++-拷贝构造函数

深拷贝与浅拷贝

**浅拷贝:**类中的缺省拷贝构造函数,对指针形式的成员变量按字节复制,而不会复制指针所指向的内容,这种拷贝方式称为浅拷贝。

cpp 复制代码
#include <iostream>
using namespace std;

class Integer{
private:
	int m_i;

public:
	Integer(int i = 0) {
		m_i = i;
	}

	void printf(void) {
		cout << m_i << endl;
	}
};
int main(int argc, const char *argv[])
{
	Integer a = 100;
	Integer b = a;//实际是将b的地址指向a的地址
	b.printf();
	Integer c(a);//类似与b
	c.printf();
	
	return 0;
}

深拷贝:为了避免浅拷贝遇到的重复重置内存问题,获得完整意义上的对象副本,必须自己定义拷贝构造函数,针对指针的成员变量,实现对指针指向内容的复制。

cpp 复制代码
#include <iostream>
using namespace std;

class Integer{
private:
	int *m_i;

public:
	Integer(int i = 0) {
		m_i = new int(i);
	}

	void printf(void) {
		cout << *m_i << endl;
	}

	~Integer(void) {
		delete m_i;
	}

	Integer(const Integer &that) {
		m_i = new int(*that.m_i);
	}
};
int main(int argc, const char *argv[])
{
	Integer a = 100;
	Integer b = a;//实际是将b的地址指向a的地址
	b.printf();
	Integer c(a);//类似与b
	c.printf();
	
	return 0;
}

拷贝赋值

当两个对象进行赋值操作时,比如"i3 = i2"编译器会讲其处理为"i3.operator = (i2)的成员函数调用形式",其中"operator="称为拷贝赋值操作符函数,由该函数完成其赋值运算,其返回结果就是表达式的结果。

如果没有自定义拷贝赋值操作符函数,编译器会为该类提供缺省的拷贝赋值操作符函数,用于完成两个对象的赋值操作。

但是编译器提供的缺省拷贝赋值函数,和缺省拷贝构造函数类似,也是浅拷贝,有"double free"和"内存泄露"的问题,这时需要自定义深拷贝赋值函数。

拷贝赋值符函数格式为:

cpp 复制代码
Integer &operation = (const Integer &that){

}

/*
Integer:类名称
&operation= :固定写法
that:指针
*/
cpp 复制代码
#include <iostream>
using namespace std;

class A{
private:
	int *m_pi;

public:
	A(int i = 0) {
		m_pi = new int(i);
	}

	void printf(void) {
		cout << *m_pi << endl;
	}

	~A(void) {
		cout << "~A" <<endl;
		delete m_pi;
	}

	A(const A &that) {
		m_pi = new int(*that.m_pi);
	}
};
int main(int argc, const char *argv[])
{
	A a = 100;
	a.printf();
	A b = a;
	b.printf();

	b = a;
	
	return 0;
}
/*运行结果报错
linux@linux:~/cplusplus$ ./a.out 
100
100
~A
~A
*** Error in `./a.out': double free or corruption (fasttop): 0x09a57008 ***
Aborted (core dumped)
*/

String类的编程实现

实现一个字符串String,为其提供可接受c风格字符串的构造函数、析构函数、拷贝构造函数和拷贝赋值函数。

cpp 复制代码
#include <iostream>
#include <cstring>
using namespace std;

class String{
private:
	char *str;

public:
	String(const char *str) {//类型转换构造函数
		this->str = new char(strlen(str) +1);
		strcpy(this->str,str);

	}
	
	String(const String &that) {//拷贝构造函数
		str = new char[strlen(that.str) +1];
		strcpy(str, that.str);
	}

	String &operator=(const String &that) {//拷贝赋值
		if (this != &that) {
			delete []str;//删除原本的地址
			str = new char[strlen(that.str) +1];//申请新地址
			strcpy(str, that.str);//拷贝内容到新地址中
		}
		return *this;
	}


	~String(void) {
		delete str;
	}
	void print(void) {
		cout << str << endl;
	}

	char *c_str(void) {
		return str;
	}
};
int main(int argc, const char *argv[])
{
	String s1 = "hello";//类型转换构造函数
	s1.print();

	String s2 = s1;//拷贝构造函数
	s2.print();

	String s3 = "world";//类型转换构造函数
	s2 = s3;//拷贝赋值
	s2.print();

	cout << s3.c_str() << endl;
	return 0;
}
相关推荐
无尽的大道3 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
爱吃生蚝的于勒7 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~10 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
binishuaio16 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE18 分钟前
【Java SE】StringBuffer
java·开发语言
就是有点傻22 分钟前
WPF中的依赖属性
开发语言·wpf
洋24031 分钟前
C语言常用标准库函数
c语言·开发语言
进击的六角龙32 分钟前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
wrx繁星点点33 分钟前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
NoneCoder1 小时前
Java企业级开发系列(1)
java·开发语言·spring·团队开发·开发