C++学习笔记21,对象赋值


 

 

C++允许将一个对象的值赋给另一个对象。

或许你认为这就是复制,然而,“复制”只在初始化对象的时候发生。

如果一个已经具有值的对象被改写了,那么更准确的来说就是“赋值”。

注意,C++提供的复制工具是复制构造函数,因为这是一个构构造函数,因此只能在对象创建的时候使用,而不能用在对象的赋值。

C++为所有的类提供了赋值工具,这个方法叫做赋值运算符,名称为operator=,实际上其实就是重载了=运算符。

例子:

 

#include <iostream>
#include <cstring>
using namespace std;
class A
{
private:
	char *str;
public:
	A(const char *s){
		int len=sizeof(s);
		str=new char[len+1];
		strcpy(str,s);
	}
	//删除复制构造函数
	A(const A &a)=delete;
	~A(){
		cout<<"start delete!"<<endl;
		delete []str;
		cout<<"delete complete!"<<endl;
	}
	A &operator=(const A &a){//赋值运算符
		if(this==&a)//注意检测是否是自赋值
			return *this;
 		int len=sizeof(a.str);
		delete []str;//重新分配str的内存
		str=new char[len+1];
		strcpy(str,a.str);
		cout<<"完成对象赋值"<<endl;
	}
	void show()const{
		cout<<"str="<<str<<endl;
		cout<<"address:&str="<<&str<<endl<<endl;
	}
};
int main()
{
	{
	A a("hello");
	cout<<"this is a:"<<endl;
	a.show();
	
	cout<<"this is b:"<<endl;
	A b("world");	
	b.show();
   
	b=a;//对象赋值
	b.show();
	/*
	cout<<"this is c:"<<endl;
	A c=b;//注意,这一个调用的也是复制构造函数,而不是赋值构造函数
	//类似于声明的语句会调用复制构造函数,原因时A c=b;c当时还没创建,是不会调用operator=方法的。
	c.show();
	*/
	}
}

结果:


可以看到,执行

b=a;//对象赋值

这一句的时候用到了赋值运算符。

如果没有定义赋值运算符,C++编译器会自动生成一个类似于默认复制构造函数行为的赋值运算符。

需要注意的是要注意检测自赋值的这种情况。

还有一种情况就是:

 

#include <iostream>
#include <cstring>
using namespace std;
class A
{
private:
	char *str;
public:
	A(const char *s){
		int len=sizeof(s);
		str=new char[len+1];
		strcpy(str,s);
	}
	//删除复制构造函数
	A(const A &a)=delete;
	~A(){
		cout<<"start delete!"<<endl;
		delete []str;
		cout<<"delete complete!"<<endl;
	}
	A &operator=(const A &a){//赋值运算符
		if(this==&a)//注意检测是否是自赋值
			return *this;
 		int len=sizeof(a.str);
		delete []str;//重新分配str的内存
		str=new char[len+1];
		strcpy(str,a.str);
		cout<<"完成对象赋值"<<endl;
	}
	void show()const{
		cout<<"str="<<str<<endl;
		cout<<"address:&str="<<&str<<endl<<endl;
	}
};
int main()
{
	{
	
	A a("hello");
	cout<<"this is a:"<<endl;
	a.show();
	/*	
	cout<<"this is b:"<<endl;
	A b("world");	
	b.show();
   
	b=a;//对象赋值
	b.show();
	*/
	cout<<"this is c:"<<endl;
	A c=a;//注意,这一个调用的也是复制构造函数,而不是赋值构造函数
	//类似于声明的语句会调用复制构造函数,原因时A c=b;c当时还没创建,是不会调用operator=方法的。
	c.show();
	
	}
}

编译结果:



这说明了 A c=a;调用的不是赋值运算符而是复制构造函数。如何区分呢?

一般来说,类似于声明的使用的是复制构造函数,类似于赋值的使用的是赋值运算符。

当然,C++11也允许显式默认和删除赋值运算符,规则和复制构造和默认构造一样。

 


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注