类与对象(中—-拷贝构造函数)

类与对象(中—-拷贝构造函数)

  • 1、概念
  • 2、特征
  • 3、拷贝构造的场景
  • 4、我们不写时,自动生成的默认拷贝构造函数
    • 4.1 日期类
    • 4.2 My Queue类

1、概念

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

2、特征

// 拷贝构造函数也是特殊的成员函数,其特征如下:
//(1)拷贝构造函数是构造函数的一个 重载形式。
//(2)拷贝构造函数的 参数只有一个且必须是类类型对象的引用。(若形参使用传值方式调用,编译器会直接报错或者引发无穷递归)
//                                                                                     拷贝构造————传值————拷贝构造(造成无穷递归)

class Date
{
public:
	//全缺省构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//拷贝构造函数
	// Date d2(d1); 拷贝构造(用 d1初始化d2,所以要先将d1传过去)
	Date(const Date& d) 
	{
		cout<< "Date(Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

private:
	int _year;
	int _month;
	int _day;
};

void Func()
{
	Date d1(2023,8,2);
    Date d2(d1);  //拷贝构造(用 d1初始化d2,所以要先将d1传过去)
	Date d3 = d1; //也是拷贝构造(另一种形式,为了兼容C语言的语法)

}

int main()
{
	Func();

	return 0;
}

3、拷贝构造的场景

//  1 3 2 6 7  要打印一下路径值path,但是打印完之后数据就丢了,所以要先拷贝构造一下path

//  Stack path;
//  Stack copy(path);
//  while (!copy.Empty())   //用拷贝构造的栈去打印数字,不会影响原来的path
//  {
//	  cout<< copy.Top() <
//	  copy.Pop();
//  }

4、我们不写时,自动生成的默认拷贝构造函数

//若未显示定义,编译器会生成默认的拷贝构造函数。
//注意:在编译器生成的默认拷贝构造函数中,内置类型成员变量是按照 字节方式 直接拷贝的(值拷贝\浅拷贝),而自定义类型成员变量 是调用其拷贝构造函数完成拷贝的。

4.1 日期类

class Date
{
public:
	//全缺省构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//默认拷贝构造函数
	/*Date(const Date& d) 
	{
		cout<< "Date(Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}*/

private:
	int _year;
	int _month;
	int _day;
};

void Func()
{
	Date d1(2023,8,2);
    Date d2(d1);  //拷贝构造(用 d1初始化d2,所以要先将d1传过去)
	

}

int main()
{
	Func();

	return 0;
}

4.2 My Queue类

//Stack类
typedef int DataType;
class Stack
{
public:
	//构造函数
	Stack(int capacity = 3)
	{
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		assert(_array);

		_capacity = capacity;
		_size = 0;
	}

	//析构函数
	~Stack()
	{
		free(_array);
		_array = nullptr;
		_capacity = _size = 0;
	}

	//默认拷贝构造函数发挥作用
	//Stack st1;
	//Stack st2(st1);  
	//这儿 st2是借助默认拷贝构造st1的(值\浅拷贝【相当于memcpy】的方式),所以st2内的 DataType* _array 与 st1内的指针指向同一块儿空间。
		  // 浅拷贝的两个缺陷:{如何解决:自己实现深拷贝(后面讲解)}
		  // (1)一个对象修改会影响另一个对象。
		  // (2)会析构两次,程序崩溃。

private:
	DataType* _array;
	int _capacity;
	int _size;
};

//MyQueue类
class MyQueue
{
public:
	void push(int x) {}
	//...

	//默认拷贝构造函数
	// MyQueue q1;
	// MyQueue q2(q1);
	// MyQueue采取默认拷贝构造的方式,其成员变量Stack可以调用它自身的拷贝构造函数实现。(MyQueue采取默认拷贝构造需要建立在  其成员变量Stack具有拷贝构造函数 的基础上)

private:
	Stack _st1;
	Stack _st2;
};

void Func()
{
	Stack st1;
	Stack st2(st1);

	MyQueue q1;
	MyQueue q2(q1);
}

int main()
{
	Func();

	return 0;
}

你可能感兴趣的:(c++)