C++拷贝赋值操作
拷贝赋值
- 介绍
- 源码
- 运行结果
- 笔记扩充(下列内容了解即可)
- 成员指针 介绍
- 成员指针 源码
- 成员指针 运行结果
介绍
- 拷贝赋值注意事项
1.拷贝赋值也有深拷贝和浅拷贝
2.如果类中没有定义赋值运算符重载函数,编译器会提供一个 默认的赋值运算符函数
3.拷贝赋值应尽可能 复用拷贝构造 和 析构函数 代码
4.尽量避免使用 指针型成员变量、缺省拷贝构造函数、缺省拷贝赋值运算符函数 因为都只是浅拷贝
5.尽量通过 引用 或 指针 向函数传递 对象型参数,减少拷贝构造,提高效率
6.若提供了自定义 拷贝构造函数 ,那么也要提供 拷贝赋值运算符函数
- 与拷贝构造相比,拷贝赋值需要做的操作有:
1.避免自赋值
2.分配新资源
3.拷贝新内容
4.释放旧资源
5.返回自引用
源码
#include<iostream>
#include<string>
using namespace std;
class Array
{friend ostream& operator<<(ostream& out,Array& arr);friend istream& operator>>(istream& out, Array& arr);
public://下标访问char& at(int index){return m_array[index];}//获取空间大小size_t size(){return m_size;}
public:// = 运算符重载Array& operator=(const Array&that){cout << "拷贝赋值函数" << endl;
#if 0//基本方法拷贝赋值if (&that != this)//判断是否重复拷贝赋值自己{//防止new失败 先用临时变量来存储char*ptemp = new char[that.m_size];if (ptemp == nullptr)//new失败后的处理方式{cerr << "Bad Allocation" << endl;return *this;}strcpy(ptemp, that.m_array);//拷贝字符串if (m_array)//判断是否为空,释放旧资源{delete[] m_array;m_array = NULL;}swap(ptemp, m_array);//如果new成功则交换数据delete[]ptemp;//以防万一手动释放一遍m_size = that.m_size;//获取空间大小}return *this;
#endif
#if 1 //大佬方法拷贝赋值if (&that != this)//判断是否重复拷贝赋值自己{Array temp(that);//利用拷贝构造操作分配新资源swap(m_array, temp.m_array);//交换新旧资源 }//当判断结束自动释放临时变量return *this;//返回操作对象
#endif}
public://初始化构造Array(size_t size = 0){cout << "构造函数" << endl;m_array = new char[size];//动态数组创建m_size = size;//记录动态数组大小}//拷贝构造Array(const Array&that){cout << "拷贝构造函数" << endl;m_array = new char[that.m_size];//创建一个同样大小的空间strcpy(m_array, that.m_array);//拷贝字符串m_size = that.m_size;//获取空间大小}//析构函数~Array(){cout << "析构函数" << endl;//销毁动态数组if (m_array){delete[] m_array;m_array = NULL;}}
private:char* m_array;//字符串数组size_t m_size;//size_t是unsigned int(无符号整形)
};
//提取(<<)重载
ostream& operator<<(ostream& out, Array& arr)
{for (int i = 0; i < arr.m_size; i++){//输出out << arr.m_array[i] << "\t";}out << endl;return out;
}
//输入(>>)重载
istream& operator>>(istream& in, Array& arr)
{for (int i = 0; i < arr.m_size; i++){//输入in >> arr.m_array[i];}return in;
}
void main()
{//单字符串输入输出Array *p_array = new Array(4);//输入cin >> *p_array;//输出cout << *p_array;cout << "--------------分隔符--------------" << endl;
//拷贝构造Array *p_array2 = new Array(*p_array);//默认拷贝构造{Array p_array4 = *p_array;//默认拷贝构造(自动析构)cout << p_array4;}cout << "--------------分隔符--------------" << endl;{//默认浅拷贝(默认赋值函数)Array *p_array3 = p_array;//默认浅拷贝(默认赋值函数)Array *p_array5;p_array5 = p_array;}
//拷贝赋值Array *p_array6 = new Array;//先构造*p_array6 = *p_array;//拷贝赋值cout << "--------------分隔符--------------" << endl;
//析构delete p_array;delete p_array2;delete p_array6;system("pause");
}
运行结果
构造函数
1253
1 2 5 3
--------------分隔符--------------
拷贝构造函数
拷贝构造函数
1 2 5 3
析构函数
--------------分隔符--------------
构造函数
拷贝赋值函数
拷贝构造函数
析构函数
--------------分隔符--------------
析构函数
析构函数
析构函数
请按任意键继续. . .
笔记扩充(下列内容了解即可)
成员指针 介绍
成员指针(用来存储 相对地址(偏移值)) 指向 成员变量的指针
成员指针 源码
#include<iostream>
#include<string>
using namespace std;
class Integer
{
public:Integer(int i = 0) :m_i(i){}int m_i;int m_a;int m_c;
};
void main()
{Integer i1(10), i2(20);int *p1 = &i1.m_i;int *p2 = &i2.m_i;//成员指针(用来存储 相对地址(偏移值)) 指向 成员变量的指针//int Integer::*p指向类中int类型变量的指针int Integer::*p = &Integer::m_i;i1.*p = 50; cout << i1.m_i << endl;cout << "--------------分隔符--------------" << endl;//偏移测试int Integer::*pp = NULL;cout << *(int*)&pp << endl;//强转类型打印值,获取偏移值pp = &Integer::m_i;cout << *(int*)&pp << endl;//强转类型打印值,获取偏移值pp = &Integer::m_a;cout << *(int*)&pp << endl;//强转类型打印值,获取偏移值pp = &Integer::m_c;cout << *(int*)&pp << endl;//强转类型打印值,获取偏移值system("pause");
}
成员指针 运行结果
50
--------------分隔符--------------
-1
0
4
8
请按任意键继续. . .