C++类和对象(中)——拷贝构造函数

前言

本文承接上文,主要介绍C++语法中的另一个极其重要的成员函数------拷贝构造函数

简要介绍

如果一个构造函数的第一个参数是自身类型的引用,且其余参数均有默认值,那么这个构造函数就是拷贝构造函数,拷贝构造的效果如下

scss 复制代码
int main()
{
	Date d1(2026, 2, 21);
	d1.Print();
	Func1(d1);
	Date d2(d1);
	d2.Print();
	return 0;
}

也就是能用已经初始化的d1初始化d2,这就是拷贝构造的效果

特点

  • 拷贝构造是构造函数重载
  • C++规定传值传参必须调用拷贝构造
  • 拷贝构造的第一个参数必须是类类型对象的引用 如果第一个参数不是引用,只是一个类类型对象,那么就会发生传值传参,调用拷贝构造,然后又会拷贝,因此必须是传引用传参,这样的话问题就迎刃而解了。
  • 如果不希望传进去的实参发生改变,那么可以加一个const从而保护实参
  • 编译器自动生成的拷贝构造函数会对内置类型进行浅拷贝(按字节一个一个拷贝),对于自定义成员会调用其拷贝构造
  • 如果一个类显示实现了析构函数并释放了资源,那么就必须显示写拷贝构造
ini 复制代码
typedef int STDataType;
class Stack
{
public:
	Stack(int n = 4)
	{
		_a = (STDataType*)malloc(sizeof(STDataType) * n);
		if (nullptr == _a)
		{
			perror("malloc申请空间失败");
			return;
		}
		_capacity = n;
		_top = 0;
	}

	// st2(st1)
	Stack(const Stack& st)
	{
		cout << "Stack(const Stack& st)" << endl;

		// 需要对_a指向资源创建同样大的资源再拷贝值
		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
		if (nullptr == _a)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		memcpy(_a, st._a, sizeof(STDataType) * st._top);
		_top = st._top;
		_capacity = st._capacity;
	}

	void Push(STDataType x)
	{
		if (_top == _capacity)
		{
			int newcapacity = _capacity * 2;
			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
				sizeof(STDataType));
			if (tmp == NULL)
			{
				perror("realloc fail");
				return;
			}
			_a = tmp;
			_capacity = newcapacity;
		}
		_a[_top++] = x;

	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	STDataType* _a;
	size_t _capacity;
	size_t _top;
};

比如栈这个结构,如果不显示写拷贝构造,那么按照字节拷贝会将st1和st2指向同一块空间,析构的时候会对一块空间析构两次,造成程序崩溃,因此需要自己写。

  • 注意一个易错点:传值返回会产生一个临时对象从而调用拷贝构造,因此应该传引用返回来减少拷贝构造的调用,返回的是返回对象的引用,但是这是如果返回的是当前函数局部域的局部对象,函数结束后对象销毁,这时引用就变成一个野引用了,因此需要保证返回对象的生命周期,当然加一个static也可以
javascript 复制代码
Stack& func2()
{
	static Stack st;//不加static的话出了作用域st就不在了
	return st;
}
int main()
{
	Stack ret = func2();
	return 0;
}

结语

拷贝构造函数到此就介绍完了,希望读者关注下文

相关推荐
仰泳的熊猫2 小时前
题目2580:蓝桥杯2020年第十一届省赛真题-分类计数
数据结构·c++·算法·蓝桥杯
qq_334903152 小时前
C++与人工智能框架
开发语言·c++·算法
2401_891482172 小时前
C++中的状态模式
开发语言·c++·算法
TTTrees2 小时前
C++学习笔记(32):智能指针(weak_ptr)
c++
qq_417695052 小时前
基于C++的区块链实现
开发语言·c++·算法
2401_894241922 小时前
基于C++的反射机制探索
开发语言·c++·算法
cui_ruicheng2 小时前
C++ 数据结构进阶:unordered_map 与 unordered_set源码分析与实现
数据结构·c++·算法·哈希算法
天赐学c语言2 小时前
Linux - 网络应用层协议HTTP
linux·c++·网络服务
wWYy.2 小时前
STL:map与unordered_map
开发语言·c++·stl