类中的6个默认函数
class A
{
};
首先,对于这样的空类,其实编译器会自己生成6个默认成员函数,取地址重载基本上不需要自己实现,主要是前面的两个
构造函数
概念: 构造函数是一种特殊的成员函数,名字与类名相同,创建类对象的时候由编译器调用, 并且在类对象的生存周期内只调用一次。 它不是去构建对象,而是去初始化对象。
特征: 1,函数名与类名相同 2,无返回值。 3,创建对象时,由编译器自动调用, 4,可以重载。
class Date
{
public:
Date()
{
_year = 2022;
_month = 5;
_day = 15;
}
Date(int year, int month, int day)
{
cout << "this==" << this << endl;
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << " " << _month << " " << _day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(1000, 10, 1);
return 0;
}
如果我们自己不写构造函数,编译器会自己生成默认的构造函数, 什么是默认构造函数: 1,自己写的无参默认,2,自己写的全缺省,3编译器给的无参 (但是默认构造函数只能有一个)
例如,下面的就有两个默认构造函数,就报错啦
class Date
{
public:
Date()
{
_year = 1900;
_month = 1;
_day = 1;
}
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void Test()
{
Date d1;
}
看看这张图,编译器不是会生成默认构造函数吗? 为什么还是随机值呢?
其实在C++中。分成了内置类型和自定义类型 内置类型:int,char,double。。。。。。 自定义类型: struct,class,union,,, 编译器生成的默认构造函数其实并不会去初始化内置类型,只会去调用自定义类型的构造函数去初始化自定义类型
class A
{
public:
A()
{
_a = 0;
_b = 1;
}
void Print()
{
cout << _a << " " << _b << endl;
}
private:
int _a;
int _b;
};
class B
{
public:
void Print()
{
cout << c << " " << d << endl;
}
private:
int c;
int d;
A aa;
};
int main()
{
B bb;
return 0;
}
析构函数
概念:用来完成类的一些资源清理工作。
特征: 1, 在类名前加上字符 ~。 2,无参数无返回值。 3,一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。 4,对象生命周期结束时,C++编译系统系统自动调用析构函数。
class Stack
{
public:
Stack()
{
int* _a = (int*)malloc(sizeof(int) * 10);
assert(_a);
_capacity = 10;
_size = 0;
}
~Stack()
{
free(_a);
_a = nullptr;
_capacity = _size = 0;
}
private:
int* _a;
int _capacity;
int _size;
};
int main()
{
Stack st;
return 0;
}
同理,和构造函数一样,如果我们不去写析构函数,那编译器生成默认析构函数, 处理自定义类型会通过调用自定义类型的析构函数去清理自定义类型。
拷贝构造函数
构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象 创建新对象时由编译器自动调用
特性是什么? 1, 拷贝构造函数是构造函数的一个重载形式。 2,拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用
class Date
{
public:
Date()
{
_year = 2022;
_month = 5;
_day = 17;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(d1);
return 0;
}
如果我们不写,编译器也会生成默认拷贝构造函数,但是这里是字节的拷贝,浅拷贝/ 值拷贝 默认生成的拷贝会存在一些问题。 例如:
class Date
{
public:
Date()
{
_year = 2022;
_month = 5;
_day = 17;
_a = (int*)malloc(sizeof(int) * 4);
}
~Date()
{
free(_a);
_a = NULL;
}
private:
int _year;
int _month;
int _day;
int* _a;
};
int main()
{
Date d1;
Date d2(d1);
return 0;
}
|