类的拷贝控制(Copy Control)

拷贝控制操作(Copy Control)

拷贝构造函数

拷贝构造函数是类内的构造函数,使用这种构造函数要将形参写为固定的const Class &类型,若程序猿没有实现拷贝构造函数则编译器会自动生成一个合成拷贝构造函数。拷贝构造函数在以下一些情况中会使用:

  1. 使用=对某类进行初始化
  2. 将一个类作为实参传给非引用的形参
  3. 将一个类作为返回值传给非引用的形参
  4. 使用花括号进行列表初始化一个数组中的元素
  5. 初始化标准化容器或者调用insert/push操作时,容器会对其元素进行拷贝和初始化

举例

#include <iostream>
#include <vector>
class test1 {
public:
	/*
	 * @brief 无参构造函数
	 */
	test1() {
		std::cout << "test1的构造函数" << std::endl;
	}

	/*
	 * @brief 拷贝构造函数
	 */
	test1(const test1& tm)
	{
		std::cout << "test1的拷贝构造函数" << std::endl;
	}
};

/*
* @brief 测试常量引用形参
*/
void testCParam(const test1& t1)
{
	std::cout << "testCParam" << std::endl;
}

/*
 * @brief 测试形参
 */
void testParam(test1 t1)
{
	std::cout << "testParam" << std::endl;
}

/*
*	@brief 测试返回对象时的拷贝构造
*/
test1 testReturn()
{
	test1 t1;
    std::cout << "testReturn" << std::endl;
	return t1;
}

int main()
{
	using namespace std;
	std::cout << "---------------------------" << std::endl;
	test1 t1;

	std::cout << "---------------------------" << std::endl;
	test1 t2 = t1;

	std::cout << "---------------------------" << std::endl;
	testCParam(t1);

	std::cout << "---------------------------" << std::endl;
	testParam(t1);

	std::cout << "---------------------------" << std::endl;
	testReturn();
	std::cout << "---------------------------" << std::endl;

	std::cout << "使用花括号进行数组初始化" << std::endl;
	test1 t3[2]{t1, t2};
	std::cout << "---------------------------" << std::endl;

	std::cout << "使用vector容器进行初始化" << std::endl;
	vector<test1> t4{ t1 };
	std::cout << "使用push_back插入元素" << std::endl;
	t4.push_back(t2);
	std::cout << "---------------------------" << std::endl;
	return 0;
}

运行结果:

---------------------------
test1的构造函数
---------------------------
test1的拷贝构造函数
---------------------------
testCParam
---------------------------
test1的拷贝构造函数
testParam
---------------------------
test1的构造函数
testReturn
test1的拷贝构造函数
---------------------------
使用花括号进行数组初始化
test1的拷贝构造函数
test1的拷贝构造函数
---------------------------
使用vector容器进行初始化
test1的拷贝构造函数
test1的拷贝构造函数
使用push_back插入元素
test1的拷贝构造函数
test1的拷贝构造函数
---------------------------

拷贝赋值运算符

拷贝赋值运算符是重载的赋值运算符,其被定义为类内的成员函数,左侧返回值为*this,右侧运算对象为所属类的类型,通常使用拷贝复制运算符会将类内的非static成员变量进行深或浅拷贝。

举例

#include <iostream>
using namespace std;
class cpyOper {
public:
	cpyOper()
	{
		cout << "无参构造" << endl;
	}
	cpyOper(const cpyOper& oper)
	{
		cout << "拷贝构造函数" << endl;
	}
	cpyOper& operator=(const cpyOper& oper)
	{
		cout << "拷贝赋值运算符" << endl;
		return *this;
	}
};
int main()
{
	cpyOper cpy1;
	cpyOper cpy2;
	cout << "------------------" << endl;
	cpy1 = cpy2;
	cout << "------------------" << endl;
	return 0;
}

运行结果:

无参构造
无参构造
------------------
拷贝赋值运算符
------------------

移动构造函数与移动赋值运算符

前情提要(左值和右值)

为了移动操作,C++标准中引入了右值引用(rvalue reference),而移动构造函数以及移动赋值运算符中也用到了移动操作。在C++中右值是临时的对象比如字面常量和表达式求值中创建的临时对象,而左值是非临时的。&&表示右值引用,&表示左值引用。

移动构造函数

移动构造函数用于获取另一个同种类别对象的资源所有权,当使用了移动构造函数后,同类对象就不应该使用而是直接销毁。移动构造函数就是在形参中加入同类对象的右值引用。

移动赋值运算符

移动赋值运算符与移动构造函数进行的操作一样,这两种操作的举例如下:

举例

#include <iostream>
using namespace std;
class test {
public:
	test() { cout << "无参构造" << endl; }

	/*
	* @brief 移动构造函数,noexcept表示移动构造不会抛出异常
	*/
	test(test&& t1) noexcept
	{
		std::cout << "移动构造函数" << std::endl;
	}
	/*
	* @brief 移动赋值运算符
	*/
	test& operator=(test&& t1) noexcept
	{
		std::cout << "移动赋值运算符" << std::endl;
		return *this;
	}
};

int main()
{
	test t1;
	test t2 = move(t1);
	cout << "-----------------------" << endl;
	test t3;
	t3 = move(t2);
	return 0;
}

运行结果:

无参构造
移动构造函数
-----------------------
无参构造
移动赋值运算符
posted @   酱油黑龙  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示