DynamicMemoryAndCopyConstructor.cppRUN

//拷贝构造函数的用法
#include <iostream>

class Vector
{
private:
	double *arr;
	int len;
	
public:
	Vector()//不带参数的普通构造函数
	{
		arr = nullptr; //指针初始化。要不nullptr,要不new的结果,要不某变量地址&something
		len = 0;
	}
	
	~Vector()//析构函数,清理
	{
		if (arr) delete[] arr; 
		//配上初始化arr = nullptr; 加上if (arr) delete[] arr; 指针的标准初始化的清除用法
	}

	Vector(const Vector& v)//拷贝构造函数:const &
	{//类成员有动态内存申请,必须写正确拷贝构造函数,内存需要深拷贝

		//1申请内存;2复制数据
		len = v.len;
		arr = new double[len];

		for (auto i = 0; i < len; i++)
		{
			arr[i] = v.arr[i];
		}
		//memcpy(arr, v.arr, sizeof(double) * len); //或者
	}

	Vector(const double *arrs, int n)
	{//类成员有动态内存申请,内存需要深拷贝

		//1申请内存;2复制数据
		len = n;
		arr = new double[len];

		for (auto i = 0; i < len; i++)
		{
			arr[i] = arrs[i];
		}
	}

	Vector & operator= (const Vector & v)//赋值函数
	{//类成员有动态内存申请,必须写正确赋值操作运算,内存需要深拷贝
		
		if (this == &v)
			return *this;//自己赋值给自己,直接返回;否则可能内存首先释放,无法完成

		//0.清除现有内存 1申请内存;2复制数据
		if (arr)delete[] arr;

		len = v.len;
		arr = new double[len];

		for (auto i = 0; i < len; i++)
		{
			arr[i] = v.arr[i];
		}

		return *this;
	}

	double operator[](int i)const //const 函数,不修改数据成员
	{
		return arr[i];
	}
	
	double & operator[](int i) //返回引用,可以类似obj[i] = 1.0; 给obj对象赋值
	{
		return arr[i];
	}

	friend std::ostream& operator<<(std::ostream& os, const Vector& v)
	{
		for (auto i = 0; i < v.len; i++)
			os << v.arr[i] << "\t";
		return os;
	}
};

void FunByValue(Vector v)
{//v通过实参拷贝构造函数得到的副本
	std::cout << v << std::endl;
}

void FunByRef(const Vector & v)
{//v,引用,就是实参本身。实参的别名方式存在
	std::cout << v << std::endl;
}

Vector CreateVector()
{//返回值以拷贝构造函数的形式返回
//但是,Microsoft C++(返回值出现拷贝构造函数调用)和GCC(没有)表现不一致

	double arr[] = { 1.1, 2.2 };
	Vector v(arr, 2);
	return v;
}

int main()
{
	double arr[] = { 1.1, 2.2 };
	Vector v1, v2(arr, 2);//构造函数

	Vector v3(v2);//拷贝构造函数
	std::cout << v3 << std::endl;

	Vector v4 = v2;//拷贝构造函数,不是赋值,v4创建并且初值
	v4 = v2;// 现在是赋值运算符了,因为v4已经存在
	std::cout << v4 << std::endl;

	//函数(按值)参数传递,出现拷贝构造函数调用
	FunByValue(v4);

	//引用方式调用,什么都不发生
	FunByRef(v4);

	std::cout << "CreateVector\n";
	//函数值返回,Microsoft C++(返回值出现拷贝构造函数调用)和GCC(没有)表现不一致
	Vector  v5 = CreateVector();
	std::cout << v5 << std::endl;

	return 0;
}