13.1 为什么不要重载 && 和 || 运算符
- 1)&&和||是C++中非常特殊的操作符
- 2)&&和||内置实现了短路规则
- 3)操作符重载是靠函数重载来完成的
- 4)操作数作为函数参数传递
- 5)C++的函数参数都会被求值,无法实现短路规则
短路原则:
重载 && 代码示例:
#include <iostream>
using namespace std;
int f1()
{
cout << "this is f1" << endl;
return 0;
}
int f2()
{
cout << "this is f2" << endl;
return 1;
}
class Complex
{
private:
int a;
int b;
public:
Complex(int a, int b)
{
this->a = a;
this->b = b;
}
Complex operator+(const Complex &c)
{
cout << "operator+" << endl;
Complex t(0, 0);
t.a = this->a + c.a;
t.b = this->b + c.b;
return t;
}
bool operator&&(const Complex &c)
{
return (this->a && c.a) && (this->b && c.b);
}
};
int main()
{
if (f1() && f2()) //短路原则:如果f1()不成立,则不会执行f2()
{
cout << "helloworld" << endl;
}
Complex c1(1, 1);
Complex c2(2, 2);
Complex c3(0, 0);
if (c1 && c2)
{
cout << "成立" << endl;
}
if (c1 && c3)
{
cout << "成立" << endl;
}
//c3.operator&&(c1 + c2) c3.operator&&(c1.operator+(c2))
if (c3 && (c1 + c2)) //重载逻辑&&违背了短路原则 所以不要重载逻辑&& ||
{
}
return 0;
}
运行结果:
13.2 数组类相关运算符的重载
13.2.3 重载数组下标运算符[ ]
- 运算符 [ ] 都只能通过成员函数重载
13.2.2 重载赋值运算符 =
- 所有的类都默认重载了 = 运算符,但是只是简单的赋值(浅拷贝),对于数组类而言,只能用深拷贝。
- 而如果在类外边通过友元函数进行重载 = 的话,系统会自动调用默认的重载函数,出现浅拷贝的问题,也就是一个内存空间被两次释放。所以 = 运算符的重载只能在类内通过成员函数进行。
步骤:
1 先释放旧的内存
2 返回一个引用
3 =操作符 从右向左
其中,在赋值前要判断是否出现自己给自己赋值的情况(如果出现这种情况没有直接返回,在下面delete后,就不能进行访问了)。也重载了一下 == 运算符。
完整示例代码:
#include <iostream>
using namespace std;
class Array
{
private:
int *data;
int size;
public:
Array(int s)
{
size = s;
data = new int[size];
}
int &operator[](int Index)
{
return data[Index];
}
bool operator==(const Array &a)
{
if (this->size != a.size)
{
return false;
}
for (int i = 0; i < size; i++)
{
if (this->data[i] != a.data[i])
{
return false;
}
}
return true;
}
Array &operator=(const Array &a) // 赋值运算符只能重载成成员函数
{
if (*this == a)
{
return *this;
}
this->size = a.size;
delete this->data;
this->data = new int[size];
for (int i = 0; i < size; i++)
{
this->data[i] = a.data[i];
}
return *this;
}
~Array()
{
if (data != NULL)
{
delete[] data;
}
}
};
int main()
{
Array a1(10); // 创建数组对象
for (int i = 0; i < 10; i++)
{
a1[i] = i + 10; // a1.operator[](i) = i + 10
}
for (int i = 0; i < 10; i++)
{
cout << a1[i] << " ";
}
cout << endl;
Array a2(5);
// a1 = a2; //所有类都默认重载了=运算符,但是只是简单的赋值(浅拷贝)
a1 = a1;
for (int i = 0; i < 10; i++)
{
cout << a1[i] << " ";
}
cout << endl;
return 0;
}
运行结果:
13.3 智能指针类auto_ptr
好像可以自己释放内存,不用自己去调用delete(不过这个智能指针已经被遗弃了)
完整示例代码:
#include <iostream>
#include <memory>
using namespace std;
class Test
{
public:
Test()
{
cout << "Test构造函数" << endl;
}
void print()
{
cout << "xxx" << endl;
}
~Test()
{
cout << "Test析构函数" << endl;
}
};
void f1()
{
Test *pt = new Test; //内存泄漏
}
void f2()
{
auto_ptr<Test> my_memory(new Test);
my_memory->print(); // 等价于my_mempry.operator->(print())
}
int main()
{
//f1();
f2();
return 0;
}
运行结果: