拷贝构造函数和赋值运算符重载的作用以及c++模板

1) 解释一下拷贝构造函数和赋值运算符重载的作用

拷贝构造函数的作用概念:拷贝构造函数是一种特殊的构造函数,是用来复制对象的。又叫做复制

构造函数。它的形式通常是ClassName(const ClassName& other),其中other是要复制的对象。

以下3种情况会调用拷贝构造:

1.使用一个已经创建完毕的对象来初始化一个新对象

2.值传递的方式给函数参数传值

3.以值方式返回局部对象

代码如下:

class Person {
public:
	int age;
	Person()
	{
		cout << "无参构造" << endl;
	}
	Person(int age)
	{
		cout << "调用有参构造" << endl;
		this->age = age;
	}
	Person(const Person& other)//拷贝构造函数的参数必须是引用(避免陷入无限递归)
   //否则当p初始化other时,参数是以值的形式传递调用拷贝构造,传参时在参数这里反复调用自己,陷入递归
   //const:1.万能引用,既能接受左值又能就接受右值2.在实参初始化形参时,形参被const修饰避免通过形参修改实参
	{
		cout << "调用拷贝构造" << endl;
		this->age = other.age;
	}
 ~Person()
	{
		cout << "析构函数" << endl;
	}
};
void fun(Person p)//参数以值的形式传递的时候会调用拷贝构造
{
    
}
Person fu()
{
	Person p;
 	return p;//p在函数里面是局部变量,(函数结束后p消失)要想在外面把p返回出来,中间要拷贝一个匿名对象p'(没有名字,只存在于当前行)
    //当前行结束匿名对象被释放,不是主函数结束才释放匿名对象
}
Person& f() //不让返回值执行拷贝构造   //函数返回值是右值,加上引用&函数返回值便是左值
//函数结束后p不会被销毁,所以不用拷贝匿名对象,便没有调用拷贝构造
{
	Person p;
 	return p;
}
void test03()//返回值
{
    fu();
}
void test04()
{
  	f();
}
void test05()
{
	Person p1 = fu();//只调用一次拷贝构造(正常是两次p-p',p'-p1),但是编译器优化掉了一次
}
int main()
{
	Person p;
	Person p1 = p;//用已经存在的对象p来初始化新的对象p1,隐式转换法调用拷贝构造
    //输出结果:无参构造,调用拷贝构造  //explicit关键字可以避免函数隐式转换法调用
    //也就是说构造函数前有explicit关键字,这里就无法用隐式转换法调用
	Person p2 = 3;//隐式转换法调用有参构造
    //结果:无参构造,调用有参构造
	Person p3;
	p3 = p;//不是初始化而是赋值,所以不调用拷贝构造
    fun(p);//值传递的方式给函数参数传值会调用拷贝构造(实参初始化形参)
    //输出结果:无参构造,调用拷贝构造
    //如果是void fun(Person& p)则不会调用拷贝构造,因为引用只是给变量起别名并没有产生新的对象
    test03();
    //输出结果:无参构造,调用拷贝构造,析构函数(p析构),析构函数(匿名对象p'析构)
    test04();
    //输出结果:无参构造,析构函数(p析构)
    return 0;
}

拷贝构造又分为浅拷贝和深拷贝

浅拷贝: (简单的赋值拷贝操作) 两个对象里面的指针成员变量指向同一块堆区内存,会造成同一块堆

区内存被重复释放(析构函数被调用两次) (没有指针变量并且不指向堆区内存) 编译器默认提供的是

浅拷贝

深拷贝:(有指针变量并且指向堆区内存)指向不同的地址,但内容大小相同 (在堆区重新申请空

间,进行拷贝操作)

代码如下:

class Person {
	int age;
	int* p;
public:
	Person()
	{
		cout << "调用无参构造" << endl;
		age = 0;
		p = nullptr;
	}
	Person(int age)
	{
		this->age = age;
		this->p = new int[age];
                for (int i = 0; i < age; i++)
		{
			p[i] = i;
		}
		cout << "调用有参构造" << endl;
	}
	Person(const Person& other)
	{
		cout << "调用拷贝构造" << endl;
		this->age = other.age;
		this->p = other.p;//浅拷贝
		this->p = new int[other.age];  //保证大小相同 //深拷贝
		for (int i = 0; i < age; i++)
		{
			this->p[i] = other.p[i];//保证内容相同
		}
	}
	~Person()
	{
		cout << "调用析构函数" << endl;
		if (p) delete[]p;
	}
};
int main()
{
	Person p(3);
	Person p1(p);
    return 0;
}

赋值运算符:赋值运算符简单来说就是浅拷贝,编译器会提供默认的赋值运算符,就是成员变量的

赋值操作

赋值运算符重载允许自定义对象赋值的操作,默认情况下,C++ 提供了浅赋值操作,但在许多情

况下,这种默认操作可能不符合要求,特别是当类中有指针成员时。重载后的赋值运算符形式通常

是ClassName& operator=(const ClassName& other)。

class person {
 string name;
	int age;
	int* password;
public:
	person()    //构造函数
	{
		password = new int(3);
	}
	~person()      //析构函数
	{
		if (password) delete password;
	}
	void operator=(const person& other)
	{
		this->name = other.name;
		this->age = other.age;
		this->password = new int(*other.password);//深拷贝
		//不能写成浅拷贝this->password=other.password
		//两个对象里面的指针成员变量指向同一块堆区内存,会造成同一块堆区内存被重复释放
	}
};
int main()
{
	person p1, p2;
	p1 = p2;//赋值调用赋值运算符
    return 0;
}

2)什么是c++模板,有哪些类型的模板

C++ 模板的概念:C++ 模板是一种泛型编程机制,它允许编写能够处理多种数据类型的代码,而

不是为每种数据类型编写重复的代码。模板提供了一种参数化类型的方式,使得代码可以在编译时

根据实际使用的数据类型进行定制。

函数模板类型

概念:函数模板是一种通用的函数定义,可以用于生成多个不同类型的具体函数。它通过模板参数

来表示可以变化的数据类型。

template<typename T>
T add(T a, T b) {
    return a + b;
}
int main() {
    int result1 = add<int>(3, 5);
    double result2 = add<double>(3.14, 2.71);
    // 函数模板根据传入的模板参数类型(<int>和<double>)生成具体的函数
    return 0;
}

类模板类型

概念:类模板是用于创建通用类的模板。它允许定义一个类的框架,其中部分成员(如成员变量、

成员函数)的类型是由模板参数确定的。

template<typename T, typename U>
class Pair {
public:
    Pair(T first, U second) : m_first(first), m.second(second) {}
    T getFirst() const { return m_first; }
    U getSecond() const { return m_second; }
private:
    T m_first;
    U m_second;
};
int main() {
    Pair<int, double> p(5, 3.14);
    // 根据模板参数<int, double>创建了一个具体的Pair类实例
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值