提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本文仅为个人笔记
视频链接:https://www.bilibili.com/video/BV1th41187DP/?spm_id_from=pageDriver&vd_source=1036f2f56be734d1fd42a8e7e38bee4c
一、构造函数
构造函数:在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态。
1.构造函数的形式
- 函数名与类名相同
- 不能定义返回值类型,也不能有return语句
- 可以有形式参数,也可以没有
- 可以是内联函数
- 可以重载
- 可以带默认参数值
2.构造函数的调用时机
在对象创建时被自动调用,并且只要定义一个对象就一定会调用构造函数。
如果程序中没有定义构造函数,则编译器会在需要的时候自动生成默认构造函数。
注意:一旦自己实现构造函数,则默认构造函数不会隐含生成,此时如果依然希望编译器隐含生成默认构造函数可以使用“=default”。
如下:
//类定义
class Clock{
public:
Clock(int newH, int newM, int newS); //构造函数
Clock()=default;//指示编译器提供默认构造函数
void setTime(int newH, int newM, int newS);
void showTime();
private:
int hour,minute,second;
};
默认构造函数也即调用时可以不需要实参的构造函数,其有两种
- 参数表为空的构造函数
- 全部参数都有默认值的构造函数
但在一个类中,两者不能同时出现,肉则编译错误。
例子如下:
可尝试单步执行跟踪
//类定义
class Clock{
public:
Clock(int newH, int newM, int newS); //构造函数
Clock();//默认构造函数
void setTime(int newH, int newM, int newS);
void showTime();
private:
int hour,minute,second;
};
//默认构造函数
Clock::Clock():hour(0),minute(0),second(0){}
//构造函数的实现
Clock::Clock(int newH, int newM, int newS){
hour = newH;
minute = newM;
second = newS;
}
void Clock::setTime(int newH, int newM, int newS){
hour = newH;
minute = newM;
second = newS;
}
inline void Clock::showTime(){
cout<<hour<<":"<<minute<<":"<<second<<endl;
}
int main(){
Clock c(6,40,0);
Clock c2;
c.showTime();
c2.showTime();
return 0;
}
3.委托构造函数
类中往往有多个构造函数,只是参数表和初始化列表不同,其初始化算法都是相同的,这时,为了避免代码重复,可以使用委托构造丞数。
如下形式:
Clock::Clock(int newH, int newM, int newS){
hour = newH;
minute = newM;
second = newS;
}
Clock::Clock():Clock(0,0,0){}//委托构造函数
4.复制构造函数
复制构造函数是一种特殊的构造函数,其形参为本类对象的引用。作用是用一个已存在的对象去初始化同类型的新对象。
- 我们经常会需要用一个已经存在的对象,去初始化新的对象,这时就需要一种特殊的构造函数——复制构造函数
- 隐含生成的复制构造函数可以实现对应数据成员的一一复制
- 自定应的复制构造函数可以实现特殊的复制功能
其形式如下:
class 类名{
public:
类名(形参); //构造函数
类名(const 类名 &对象名); //复制构造函数
// ...
};
类名::类(const 类名&对象名) //复制构造函数的实现
{
函数体
}
复制构造函数被引用的三种情况:
- 定义一个对象时,以本类另一个对象作为初始值,发生复制构造;
- 如果函数的形参是类的对象,调用函数时,将使用实参对象初始化形参对象,发生复制构造
- 如果函数的返回值是类的对象,函数执行完返回主调函数时,将使用return语句中的对象初始化成一个临时无名对象,传递给主调函数,此时发生复制构造
class Point{
public:
Point(int xx=0,int yy=0){x==xx;y==yy;}//构造函数、内联
Point(const Point&p);//复制构造函数
void setX(int xx){x==xx;}
void setY(int yy){y==yy;}
int getX() const {return x;}
int getY() const {return y;}
private:
int x,y;
};
//复制构造函数的实现
Point::Point(const Point&p){
x = p.x;
y = p.y;
cout<<"Calling the copy constructor"<<endl;
}
//形参为Point类对象
void fun1(Point p){
cout<<p.getX()<<endl;
}
//返回值为Point类对象
Point fun2(){
Point a(1,2);
return a;
}
int main(){
Point a(4,5);
Point b(a); //用a初始化b
cout<<b.getX()<<endl;
fun1(b); //对象b作为fun1的形参
b = fun2();//函数的返回值为类对象(由于编译器的优化功能,此处可能不会调用复制构造函数)
cout<<b.getX()<<endl;
return 0;
}
二、析构函数
- 完成对象被删除前的一些清理工作
- 在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间
- 如果程序未声明析构函数,编译器会将自动生成一个默认的析构函数,函数体为空
注:析构函数不能有参数
class Point{
public:
Point(int xx,int yy);
~Point();//析构函数
//其他函数原型
private:
int x,y;
};
Point::Point(int xx,int yy){
x = xx;
y = yy;
}
Point::~Point(){}