构造函数
构造函数就是与类名同名的成员函数,当实例化对象时它会自动执行,当构造函数执行结束后,对象才完成实例化
任务:一般负责对类对象进行初始化、资源分配
class 类名
{
int* p;
public:
类名(参数)
{
p = new int;
}
};
1、构造函数必须是public,否则无法实例化对象
2、构造函数可以重载,可以有多个版本的构造函数(无参、有参)
3、带参数的构造函数的调用
类名 对象名(实参); // 使用实参调用有参构造
类名* 对象名 = new 类名(实参); // 使用实参调用有参构造
4、默认情况下编译器会自动生成一个什么都不干的无参构造函数,但一旦显式地实现了构造函数,就不再自动生成该无参构造函数了
5、如果给有参构造设置了默认形参,实例化对象时可以出现类似调用无参构造的语句,但实际是调用有参构造
6、构造函数没有返回值
7、不能使用malloc给类对象分配内存,因为它不会调用构造函数
析构函数
任务:析构函数一般负责对类对象内容进行收尾工作,例如:释放资源、保存数据等
当对象销毁时会自动执行
class 类名
{
int* p;
public:
类名 (参数) //有参构造
{
p = new int;
}
~类名(void) //析构函数
{
delete p;
}
};
1、析构函数也必须是public
2、析构函数没有参数、没有返回值、不能重载
3、当类对象生命周期完结,被操作系统自动释放(栈),或者通过delete手动释放(堆) 才会调用析构函数
#include <iostream>
using namespace std;
class Test
{
public:
/*
Test(void)
{
cout << "我是Test的无参构造" << endl;
}
*/
Test(int num = 88)
{
cout << "我是Test的有参构造 " << num << endl;
}
~Test(void)
{
cout << "我是Test的析构函数" << endl;
}
};
int main(int argc,const char* argv[])
{
Test t; //栈内存,程序结束自动释放,因此也会调用析构
// Test t(44);
Test* t1 = new Test(77);
delete t1; //调用了析构
}
4、构造函数必定执行,但析构函数不一定会执行
5、不能使用free销毁类对象,因为不会调用析构函数
6、如果没有显式地实现析构函数,编译器也会自动生成一个什么都不做的析构函数
初始化列表
初始化列表是属于构造函数的一种特殊语法,只能在构造函数中使用
class 类名
{
const 成员1;
成员2;
public:
类名(参数) : 成员1(val),成员2(val) // 初始化语句 val可以是常量、变量
{
//成员1 = val; 属于赋值语句 不是初始化 带const属性的成员就无法赋值
}
};
注意:
1、初始化列表是先于构造函数执行,初始化列表执行时类对象还没有实例化完成,因此它是一种给const属性成员变量初始化的最佳方案
2、当参数名与成员名相同时,初始化列表可以分辨出来,可以同名
3、当成员中有类类型,该成员的有参构造函数可以在初始化列表中调用
#include <iostream>
using namespace std;
class Test
{
public:
Test(int num)
{
cout << "Test的有参构造" << endl;
}
};
class Data
{
const int num;
Test t;
public:
Data(int num):num(num),t(10)
{
// num = _num;
cout << "Data的有参构造" << endl;
}
void show()
{
cout << num << endl;
}
};
int main(int argc,const char* argv[])
{
Data d(88); //先调用Test的有参构造,再调用Data的有参构造
d.show();
}
标签:初始化,函数,C++,析构,public,类名,构造函数
From: https://www.cnblogs.com/ljf-0804/p/17653714.html