C++类和对象之析构函数和拷贝构造函数

一、析构函数

其实这个析构函数也是不处理内置类型,自定义类型的会调用编译器自己的默认构造 

 还有就是我自己在做题的时候遇到一个问题,全局变量和静态变量以及在main函数里面创建的局部的变量,这三个变量的构造顺序以及析构的顺序,我把这个题先截下图

 就是这个题,首先我们要知道,全局的对象先于局部对象进行构造,局部对象(包括static)都是按照顺序进行构造的,所以这个题的构造顺序肯定是CABD, 然后注意这个析构顺序,他是按照构造相反顺序进行析构的,只需要注意一下static需要等待程序结束才会进行析构,也就是说main函数执行完毕以后才进行析构,然后全局变量C由于是第一个创建的所以最后释放掉,所以析构顺序就是BADC

 

//Stack(const Stack& st)

// {

// cout << "Stack(const Stack& st)" << endl;

//

// _a = (int*)malloc(sizeof(int)*st._capacity);

// if (_a == nullptr)

// {

// perror("malloc fail");

// exit(-1);

// }

// memcpy(_a, st._a, sizeof(int)*st._top);

// _top = st._top;

// _capacity = st._capacity;

// }

//

// ~Stack()

// {

// cout << "~Stack()" << endl;

//

// free(_a);

// _a = nullptr;

// _top = _capacity = 0;

// }

//

// void Push(int x)

// {

// // ....

// // 扩容

// _a[_top++] = x;

// }

//

//private:

// int* _a;

// int _top;

// int _capacity;

//};

//class MyQueue {

//public:

// void push(int x)

// {

// _pushST.Push(x);

// }

//private:

// Stack _pushST;

// Stack _popST;

// size_t _size = 0;

//};

这里有两个类第一个是Stack类,第二个是MyQueue类,像第一个这个类里面的成员变量都是内置的类型变量,而且还有定义了一个int类型的指针,需要去释放这个空间,所以需要我们自己去写一个析构函数,而第二个这个MyQueue类其实就不需要我们去写析构函数了,因为它都是自定义的类型的成员变量

二、拷贝构造函数

这个图告诉我们为啥拷贝构造函数里面的参数必须是引用,因为要是传值操作的话,会进行一个拷贝,这样就相当于无穷递归下去了 

拷贝构造的方式就是比如我们写的是stack类,然后拷贝构造就是 stack(const satck&....)里面传一个参数就行

这个图只有Func1调用了拷贝构造函数,因为Func1里面是传值,而传值要进行一次拷贝,这个拷贝就正好调用了拷贝构造函数,而Func2就不行,因为它里面的参数是引用,这个引用形参是实参的别名,并不会有拷贝这个操作

还有就是自定义类型的拷贝肯定是需要我们自己去写的,因为自定义类型很复杂,自己定义的类型编译器肯定会懵,而那些内置类型的数据的拷贝编译器自己就拷贝了,就像什么int啊double啊,这些编译器都知道,就不需要我们再去为这些内置类型数据去写拷贝构造了

像下面这个例子stack就得写一个自己的拷贝构造函数,因为要是不写拷贝构造的话,相当于,一个空间被释放了两次,这样是不行的,相当于第二次那个释放了个寂寞

 

 

就像这样重载了==,这个重载是放在了类里面,因为要是放在外面的话访问不了私有成员(当然我们可以在类里面定义一个get接口去访问这个私有成员),然后为啥要引用呢,是因为要是改成值传递的话,那么就会调用拷贝构造函数

bool operator==(const Date& d)

{

return _year == d._year

&& _month == d._month

&& _day == d._day;

}

// d1 > d2

bool operator>(const Date& d)

{

if (_year > d._year)

{

return true;

}

else if (_year == d._year && _month > d._month)

{

return true;

}

else if (_year == d._year && _month == d._month && _day > d._day)

{

return true;

}

return false;

}

// d1 >= d2

bool operator>=(const Date& d)

{

return *this > d || *this == d;

}

咱就看这个>=的运算符重载就很巧妙啊,因为前面重载了> 和 == 那我们在重载>=的时候完全可以用这两个重载。

记住一个就是闰年的计算方法就是,四年一闰年,百年不闰年,四百年再闰年一次下面这个就是返回每个月天数的函数方法的实现

下面这里有一个实现+=运算符和+运算符的区别,注意一下+=的函数返回值是引用,而+的函数返回值是值返回

 这个是实现+=运算符的重载

这个是+运算符的重载

 二者的区别就在于那个引用,上面+=是需要改变*this对象的值的,它出了作用域是不能被销毁的,而下面这个单纯加,并不能改变原先对象的值,所以不能用引用传递,就要用值传递

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值