文章概述
- 重载左移操作符和右移操作符
- 重载等号操作符
重载左移操作符和右移操作符
a. 我们首先知道<<,>>的顺序是从左往右执行的。
int a=2;
//cout<<a; cout<<endl;
cout<<a<<endl;
b. 代码:重载<<运算符
class Test
{
//friend void operator<<(ostream&out, Test& a); ostream&
friend ostream& operator<<(ostream&out, Test& a);
private:
int x;
public:
Test()
{
x = 1;
cout << "对象被创建" << endl;
}
~Test()
{
cout << "对象被释放" << endl;
}
};
//void operator<<(ostream&out,Test& a)
//{
// cout << a.x << endl;
//}ostream&
ostream& operator<<(ostream&out,Test& a)
{
cout << a.x << endl;
return out;
}
int main()
{
Test a;
//int i=1; 由cout<<i<<endl;能不能将对象输出cout<<a<<endl;
//需求:cout << a ; 通过需求写出函数声明: void operator << (ostream&out,Test& a)
//1.通过友元函数实现需求:
cout << a;
//2. 因为成员函数cout.operator(Test&a),我们不能访问ostream类。这也就是友元函数的应用场景
//3. 新的需求: cout<<a<<endl;<<运算符的顺序是从左往右执行的.即cout<<a应该有个返回值
// ostream& operator<<(ostream&out,Test& a)
cout << a << "abc"<<endl;
return 0;
}
c. 代码: 重载>>运算符
class Test
{
friend istream& operator>>(istream&in, Test& a);
private:
int x;
public:
Test()
{
x = 1;
cout << "对象被创建" << endl;
}
~Test()
{
cout << "对象被释放" << endl;
}
void PrintF()
{
cout << this->x << endl;
}
};
istream& operator>>(istream&in, Test& a)
{
cin >> a.x;
return in;
}
int main()
{
Test a,b;
cin >> a >>b;
a.PrintF();
b.PrintF();
return 0;
}
重载等号操作符(赋值操作)
a. 类对象中只有普通变量时:
class Test
{
private:
int x;
public:
Test()
{
x = 1;
cout << "对象被创建" << endl;
}
Test(int x)
{
this->x = x;
cout << "对象被创建" << endl;
}
~Test()
{
cout << "对象被释放" << endl;
}
void PrintF()
{
cout << this->x << endl;
}
};
int main()
{
Test a(5),b(8);
//分析b=a 内存中发生了什么?
b = a;
return 0;
}
b. 类对象中有指针变量的时候:
class Test
{
private:
int* p;
public:
Test(int x)
{
this->p = new int(x);
cout << "对象被创建" << endl;
}
~Test()
{
if (p!=NULL)
{
delete p;
}
cout << "对象被释放" << endl;
}
int* getP()
{
return p;
}
};
int main()
{
Test a(5),b(8);
//获得赋值前对象中指针的地址
cout << a.getP() << endl;
cout << b.getP() << endl;
b = a;
//获得赋值后对象中指针的地址
cout << a.getP() << endl;
cout << b.getP() << endl;
//分析: 程序释放对象的时候会崩溃 ?why?
return 0;
}
上面是执行默认的赋值操作,会出现问题。我们下面重载赋值运算符,达到深拷贝的目的。
class Test
{
private:
int* p;
public:
Test(int x)
{
this->p = new int(x);
cout << "对象被创建" << endl;
}
~Test()
{
if (p!=NULL)
{
delete p;
}
cout << "对象被释放" << endl;
}
int* getP()
{
return p;
}
//赋值运算符实现深拷贝
Test& operator=(Test& a)
{
if (this->p!=NULL)
{
delete p;
}
p = new int(*a.p);
return *this;
}
};
//深拷贝和浅拷贝的区别: 深拷贝需要重新开辟内存空间 浅拷贝不需要重新开辟内存空间
//当类中有指针变量的时候,我们需要手动的写运算符重载(赋值),实现深拷贝
int main()
{
Test a(5),b(8);
//根据需求: b=a 得出声明: operator=(Test& a)
b = a;
return 0;
}
总结:
a. 友元函数重载运算符使用注意点:
- 运算符的左右操作类型不同的时候我们使用友元函数重载运算符;
Test a;
a =a+25;
- 友元函数没有this指针,所需的操作数都必须在参数列表中显示声明,所以很容易实现类型的转换
- C++中不能用友元函数重载的运算符:
= [] () ->
b. 重载赋值运算符的步骤:
Test a,b;
b=a;
- 首先释放b的内存
- 根据a的内存大小为b重新开辟内存空间
- 最后将指针b的内容给a
注意: (1). 函数返回值当左值的时候,必须返回引用;
(2). 不要返回一个临时变量的引用或者指针。