1)构造函数
2)默认构造函数
3)重载构造函数
4)构造函数与new
5)全局对象的构造先于main函数
6)析构函数
7)析构函数与数组
8)析构函数与delete运算符
9)析构函数可以显式调用
1.构造函数
构造函数是特殊的成员函数。
创建 类 类型的新对象,系统自动会调用构造函数。
构造函数是为了保证对象的每个数据成员都被正确初始化。
构造函数的写法:
函数名和类名完全相同
不能定义构造函数的类型(返回类型),即使是void也不行
通常情况下构造函数应声明为公有函数,否则它不能像其它成员函数那样被显式地调用
构造函数被声明为私有,有特殊地用途
构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)
/*Test类的.h 文件用于声明*/
#ifndef _TEST_H_
#define _TEST_H_
class Test {
private:
int num_;
public:
Test();
};
#endif // !_TEST_H_
/*Test类的实现.cpp*/
#include <iostream>
#include "Test.h"
using namespace std;
//不带参数的构造函数称为默认构造函数
Test::Test()
{
num_ = 0;
cout << "Initializing Default " << endl;
}
/*测试文件.cpp*/
#include "Test.h"
int main(void)
{
Test t;
return 0;
}
2)默认构造函数
不带参数的构造函数。
如果程序中未声明任何一个构造函数,则系统自动产生出一个默认构造函数。如果我们定义了一个构造函数,即使不是默认构造函数,系统也不会给我们产生默认构造函数了。
3)重载构造函数
和重载的定义一样,会根据参数的类型,数量,顺序不同,选择合适的重载构造函数。
4)构造函数与new
/*Test类的.h 文件用于声明*/
#ifndef _TEST_H_
#define _TEST_H_
class Test {
private:
int num_;
public:
Test();
Test(int a);
void Display();
~Test();
};
#endif // !_TEST_H_
/*Test类的实现.cpp*/
#include <iostream>
#include "Test.h"
using namespace std;
//不带参数的构造函数称为默认构造函数
Test::Test()
{
cout << "Initializing Default " << endl;
}
Test::Test(int a)
{
num_ = a;
cout << "带参构造函数 " << endl;
}
Test::~Test() //析构函数不能重载
{
cout << "Destroy " << num_ << endl;
}
void Test::Display()
{
cout << "num_ = " << num_ << endl;
}
#include "Test.h"
int main(void)
{
Test t1;
t1.Display();
Test t2(10);
t2.Display();
Test* t3 = new Test(20); //这里不仅开辟了内存,而且调用了析构函数
t3->Display();
delete t3;
return 0;
}
/*
输出结果:
Initializing Default //调用默认构造函数
num_ = -858993460 //未初始化num_,为垃圾值
带参构造函数
num_ = 10
带参构造函数
num_ = 20
Destroy 20 //先销毁程序员使用new开辟的空间堆上的空间
Destroy 10 //再销毁栈上的空间,先创建的后释放,(和栈的特性一样,先进后出)
Destroy -858993460*/
5)全局对象的构造先于main函数这里的测试用到上面的Test.h和Test.cpp
#include "Test.h"
#include <iostream>
using namespace std;
Test t(10);//全局的对象
int main(void)
{
cout << "Entering main ......" << endl;
cout << "Entering main ......" << endl;
return 0;
}
/*
输出结果:
带参构造函数 //调用全局对象的构造函数先于main函数
Entering main ......
Entering main ......
Destroy 10
*/
6)析构函数
函数名和类名相似(前面多了一个字符“~”)。
没有返回类型
没有参数。
析构函数不能被重载
如果没有定义析构函数,编译器会自动生成一个默认析构函数,其格式如下:
类名::默认析构函数名()
{
}
默认析构函数是一个空函数。
7)析构函数与数组
#include "Test.h"
#include <iostream>
using namespace std;
int main(void)
{
Test t[2] = {10,20};
Test* t2 = new Test(2);
delete t2;
Test* t3 = new Test[2];
delete []t3; //不仅释放了内存,而且调用了析构函数
return 0;
}
/*
输出:
带参构造函数 10
带参构造函数 20
带参构造函数 2
Destroy 2
Initializing Default
Initializing Default
Destroy -842150451
Destroy -842150451
Destroy 20
Destroy 10
*/
9)析构函数可以显式调用
#include "Test.h"
#include <iostream>
using namespace std;
int main(void)
{
Test t; //对象结束时会自动调用析构函数
t.~Test();//再一次调用析构函数,不推荐显示调用析构函数,很少用。
return 0;
}
/*
输出:
Initializing Default
Destroy -858993460 //这里析构函数被调用了两次
Destroy -858993460
*/