二、左移运算符重载
作用:可以输出自定义数据类型(像基本类型一样)
注:只能利用全局函数重载左移运算符
C++中的左移运算符<<是一个二元运算符,其左操作数为调用对象,右操作数为传入的参数。如果将左移运算符重载为成员函数,那么左操作数就必须是类的对象,而右操作数可以是任意类型。这样做的问题在于,当左操作数是非自定义类型时(如int、double等),无法直接调用成员函数进行重载。
一)代码操作
//1.<<的第一种重载版本(缺陷:无法输出多个对象,例如:cout<<adjusted<<diff;报错)
// void operator<<(ostream &os,const Time &t)
// {
// os<<t.hours<<"hours,"<<t.minutes<<"minutes"<<endl;
// }
//2.<<的第二种重载版本(可以进行连续输出)
ostream &operator<<(ostream &os,Time &t)//os标准输出流对象
{
os<<t.hours<<"hours,"<<t.minutes<<"minutes"<<endl;
return os;//如果要连续输出,必须返回os,不能返回局部变量(局部变量函数结束后自动销毁,一次性),所以必须要用系统提供的os(形参)
}
二)输出员工信息
代码示例:
#include <iostream>
#include <string>
using namespace std;
class Employee{
private:
string name;
int salary;
public:
Employee():name{},salary{}{}
Employee(string name,int salary):name{name},salary{salary}{}
string getName()const
{
return name;
}
int getSalary()const
{
return salary;
}
};
ostream &operator<<(ostream &cout,Employee &emp)
{
cout<<"员工信息如下:"<<"姓名:"<<emp.getName()<<",薪水:"<<emp.getSalary()<<"元"<<endl;
return cout;
}
int main()
{
Employee emp("gaoyinjie",5000);
Employee emp1("wanglei",6000);
cout<<emp<<emp1;
return 0;
}
运行结果:
员工信息如下:姓名:gaoyinjie,薪水:5000元
员工信息如下:姓名:wanglei,薪水:6000元
三、赋值运算符重载
一)深拷贝和浅拷贝的区别
浅拷贝是指将一个对象的引用复制到另一个对象,这样两个对象会共享同一块内存空间。当其中一个对象发生改变时,另一个对象也会随之改变。浅拷贝通常只复制对象本身,而不会复制对象内部的引用类型数据。
深拷贝是指将一个对象以及其内部所有的引用类型数据都复制到另一个对象,这样两个对象是完全独立的,彼此之间互不影响。深拷贝会递归复制对象的所有引用类型数据,确保复制的对象与原始对象完全独立。
在实际编程中,根据需求选择合适的拷贝方式非常重要。如果需要独立的对象副本,应该使用深拷贝;如果只需要共享数据或者节省内存空间,可以使用浅拷贝
例如,类内指针成员拷贝, 如果使用浅拷贝,析构函数释放内存时,可能会出现同一块内存重复释放的问题。所以要使用深拷贝。
二) 深拷贝操作
代码示例:
#include <iostream>
using namespace std;
class Person{
public:
int *m_age;
Person(int age)
{
m_age = new int(age);
}
//释放
~Person(){
if(m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
};
int main()
{
Person p1(10);
cout<<"p1的年龄:"<<*p1.m_age<<endl;
Person p2(20);
cout<<"p2的年龄:"<<*p2.m_age<<endl;
cout<<"---------------"<<endl;
p1 = p2;
cout<<"p1的年龄:"<<*p1.m_age<<endl;
cout<<"p2的年龄:"<<*p2.m_age<<endl;
return 0;
}
运算结果:
p1的年龄:10
p2的年龄:20
---------------
p1的年龄:20
p2的年龄:20
三)赋值运算符操作
赋值运算符代码示例;
Person &operator=(Person &p)
{
if(m_Age != nullptr)//判断指针是否为空,如果不为空,清空指针
{
delete m_Age;
m_Age = nullptr;
}
m_Age = new int(*p.m_Age);//重新开辟指针地址,并赋值
return *this;//返回Person对象,可以重复赋值
}