1.类和对象
1.1构造函数和析构函数(补充)
1.对于默认的构造函数而言,一旦我们定义了其他的构造函数,除非我们再定义一个默认的构造函数,否则类将没有默认的构造函数。
2.合成的默认构造函数只适合非常简单的类,因为对于某些类而言,合成的默认构造函数可能执行错误的操作。
3.有些时候编译器不能为某些类合成默认的构造函数。
4.在类外部定义构造函数
cpp
Date::Date(std::istream &is)
{
read(is,*this);//read函数的作用是从is中读取一条交易信息然后存入this对象中
}
1.2缺省参数
cpp
Date(int year=1,int month=1,int day=1)
{
_year=year;
_month=month;
_day=day;
}
//当你传参传入的参数不足时,编译器自动按缺省值给。
//声明的时候给缺省值
private:
int _year=1;
int _month=1;
int _day=1;
//此为声明,定于在main函数中
1.3析构函数
1.有资源需要显示清理,就需要析构函数。
2.有两种场景不需要写析构。
(1)没有资源清理。
(2)内置类型成员没有资源清理。剩下都是自定义类型。
1.4拷贝构造函数
拷贝函数:拷贝构造函数是一种特殊的构造函数,用于创建一个新对象,并用另一个已存在的同类型对象来初始化它。
1.拷贝构造函数是构造函数的一个重载形式。
2.拷贝构造函数的参数只有一个且必须是类类型的引用,使用传值方式编译器会直接报错。(会引发无穷递调用)。
3.若未显示定义,编译器会生成默认的拷贝构造函数。
4.简单示例:
cpp
#include <iostream>
class MyClass {
private:
int* data;
public:
MyClass(int value) {
data = new int(value);
}
// 自定义拷贝构造函数进行深度复制
MyClass(const MyClass& other) {
data = new int(*other.data);
}
~MyClass() {
delete data;
}
void display() {
std::cout << "Value: " << *data << std::endl;
}
};
int main() {
MyClass obj1(10);
MyClass obj2 = obj1; // 调用拷贝构造函数
obj1.display();
obj2.display();
return 0;
}
5.深度复制和浅度复制
- 默认情况下,编译器生成的拷贝构造函数进行浅度复制,即只复制成员变量的值,而对于指针类型的成员变量,只是复制指针的值,而不是指针所指向的内容。这可能会导致两个对象中的指针指向同一块内存,当其中一个对象被销毁时,可能会导致另一个对象的指针成为悬空指针。
- 为了避免这种情况,可以自定义拷贝构造函数,进行深度复制,即复制指针所指向的内容,使得两个对象拥有独立的内存空间。
cpp
Date(Date& d)
{
_year = d._year; //内置类型按字节拷贝。
_month = d. _month; //自定义类型会去调用其拷贝构造函数。
_day = d._day;
}
int main()
{
//两种拷贝方式相同
Date d3 (d4);
Date d4 = d2;
return 0;
}
一般情况下,不需要析构就不需要拷贝。