总结:
1、等号操作符重载和拷贝构造函数重载一般用在数据成员中需要单独在堆区开辟内存时(指针)
2、new,delete重载内部还是使用malloc和free
3、逗号表达式(,)、或者(||),且(&&),条件表达式(?:)具有短路功能。
但重载后失去此功能,故不建议重载这两个运算符
4、自定义智能指针auto_ptr(在c++11新特性中已经被移除)是一个模板类。
可以自动被回收,自动释放
等号操作符重载:
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Student {
public:
Student() {
this->id = 0;
this->name = NULL;
}
Student(int id, char *name) {
this->id = id;
//this->name = name; 浅拷贝 错误
this->name = new char[strlen(name) + 1];
//this->name = name; 赋值错误
strcpy(this->name, name);
}
Student(const Student& another) {
this->id = another.id;
//深拷贝
this->name = new char[strlen(another.name) + 1];
strcpy(this->name, another.name);
}
Student& operator=(const Student& another) {
if (this == &another) //防止自身赋值
return *this;
//先将自身的额外开辟的空间回收掉
if (this->name != NULL) {
delete this->name;
this->name = NULL;
this->id = 0;
}
//执行深拷贝
this->id = another.id;
this->name = new char[strlen(another.name) + 1];
strcpy(this->name, another.name);
return *this;
}
void printS() {
cout << "id:"<<this->id << " name:" << this->name << endl;
}
~Student() {
if (this->name != NULL) {
delete this->name;
this->name = NULL;
this->id = 0;
}
}
private:
int id;
char *name;
};
void test01() {
Student s1(1, "zhangdan");
Student s2 = s1; //调用拷贝构造
s2.printS();
Student s3(2,"lisi");
s2 = s1; //赋值操作符 默认的赋值操作符为浅拷贝 只是简单的指针指向
//两次析构 其中一次为空
s2.printS();
}
/*
id:1 name:zhangdan
id:1 name:zhangdan
*/
int main()
{
test01();
return 0;
}
#endif
new和delete操作符重载:
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A()..." << endl;
}
A(int a) {
cout << "A(int)..." << endl;
this->a = a;
}
//重载的new操作符 依然会触发对象的构造函数
void* operator new(size_t size) {
cout << "重载new操作符" << endl;
return malloc(size);
}
void* operator new[](size_t size) {
cout << "重载new[]操作符" << endl;
return malloc(size);
}
void operator delete(void *p) {
cout << "重载了delete操作符" << endl;
if (p != NULL) {
free(p);
p = NULL;
}
}
void operator delete[](void *p) {
cout << "重载了delete[]操作符" << endl;
if (p != NULL) {
free(p);
p = NULL;
}
}
~A() {
cout << "~A().... " << endl;
}
private:
int a;
};
void test01() {
int *value_p = new int;
A *ap = new A(10);
//等价于
//ap->operator new(sizeof(A));
delete ap;
}
/*
重载new操作符
A(int)...
~A()....
重载了delete操作符
*/
void test02() {
int *array = (int *)malloc(sizeof(int) * 80);
A *array_p = new A[5];
//等价于
//array_p->operator new[](sizeof(A[5]));
delete[] array_p;
}
/*
重载new[]操作符
A()...
A()...
A()...
A()...
A()...
~A()....
~A()....
~A()....
~A()....
~A()....
重载了delete[]操作符
*/
int main(void)
{
test01();
cout << "test02" << endl;
test02();
return 0;
}
#endif
&&和||操作符重载(不建议使用,使用了短路功能):
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
Test(int value) {
this->value = value;
}
Test operator+(Test &another)
{
cout << "执行了+操作符重载" << endl;
Test temp(this->value + another.value);
return temp;
}
bool operator&&(Test &another)
{
cout << "执行了&&操作符重载" << endl;
if (this->value && another.value) {
return true;
}
else {
return false;
}
}
bool operator||(Test &another)
{
cout << "重载了||操作符" << endl;
if (this->value || another.value) {
return true;
}
else {
return false;
}
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int value;
};
void test01() {
Test t1(0);
Test t2(20);
//重载&&操作符,并不会发生短路现象。
if (t1 && t2) { //t1.operator&&(t2)
cout << "为真" << endl;
}
else {
cout << "为假" << endl;
}
}
/*
执行了&&操作符重载
为假
~Test()...
~Test()...
*/
void test02() {
int a = 0;
int b = 20;
if (a && (a = 10)) { //a为0的话,a+b 就不会执行 短路
cout << "true" << endl;
}
cout << "a:" << a << endl;
Test t1(0);
Test t2(20);
//重载&&操作符,并不会发生短路现象。
if (t1 && (t1 + t2)) { //t1.operator&&(t1.operator+(t2))
cout << "为真" << endl;
}
else {
cout << "为假" << endl;
}
}
/*
a:0
执行了+操作符重载
~Test()...
执行了&&操作符重载
~Test()...
为假
~Test()...
~Test()...
*/
void test03() {
Test t1(0);
Test t2(20);
//重载||操作符,并不会发生短路现象
if (t1 || (t1 + t2)) {//t1.operator||( t1.operator+(t2) )
cout << "为真" << endl;
}
else {
cout << "为假" << endl;
}
}
/*
执行了+操作符重载
~Test()...
重载了||操作符
~Test()...
为真
~Test()...
~Test()...
*/
int main(void)
{
int a = 1;
int b = 20;
test01();
cout << "test02" << endl;
test02();
cout << "test03" << endl;
test03();
return 0;
}
#endif
自定义智能指针(stl中模板类,指针用完自动回收,不需要手动delete):
#if 1
#include<iostream>
using namespace std;
#include<memory>
//智能指针是自动被回收,自动释放
//只能指针是一个模板类
class A
{
public:
A(int a)
{
cout << "A()..." << endl;
this->a = a;
}
void func() {
cout << "a = " << this->a << endl;
}
~A() {
cout << "~A()..." << endl;
}
private:
int a;
};
void test01() {
int *p = new int;
*p = 20;
delete p;
}
void test02() {
//int *p = new int;
//等价于
auto_ptr<int> ptr(new int);
*ptr = 100;
}
void test03() {
#if 0
A* ap = new A(10);
ap->func();
(*ap).func();
delete ap;
#endif
//等价于
auto_ptr<A> ap(new A(10));
ap->func();
(*ap).func(); //智能指针用完后 自动回收 调用析构函数
}
/*
A()...
a = 10
a = 10
~A()...
*/
class MyAutoPtr {
public:
MyAutoPtr(A* ptr) {
this->ptr = ptr; //ptr=new A(10)
}
~MyAutoPtr() {
if (this->ptr != NULL) {
cout << "delete ptr" << endl;
delete ptr;
ptr = NULL;
}
}
A* operator->() {
return this->ptr;
}
A& operator*()
{
return *ptr; //*ptr表示返回对象本身
}
private:
A *ptr; //内部指针
};
void test04() {
MyAutoPtr myp(new A(10));
myp->func(); //myp.ptr->func()
(*myp).func();//*ptr.func()
}
/*
A()...
delete ptr
~A()...
*/
int main(void) {
//test02();
//test03();
test04();
return 0;
}
#endif