构造函数和析构函数
本文原创,转载需注明原作者。
什么是构造函数和析构函数?
构造函数就是在一个类被建立的时候自动执行的函数。
析构函数就是在一个类被销毁的时候自动执行的函数。
例如下面这段代码:
#include<bits/stdc++.h>
using namespace std;
class A{
public:
A(){
cout<<"created."<<endl;
}
~A(){
cout<<"destroyed."<<endl;
}
};
class A test;
int main(){
cout<<"main."<<endl;
}
输出结果:
created.
main.
destroyed.
可以看到,created在main之前输出,说明在定义一句“class A test”这一句中就已经执行了这个构造函数。
在main结束后,test变量被自动销毁,输出destroyed。
构造函数的写法
考虑如下的代码:
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
A(int i){
a=i;
}
};
int main(){
A test(5);
cout<<test.a;
}
可以看到,构造函数和普通的成员函数写法类似,但是没有返回值。构造函数名称必须和类名一致。
在定义变量的时候,只需要在变量名之后写上括号和参数即可。
构造函数注意事项
如果我们定义了一个构造函数,但是没有调用,会发生什么?
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
A(int i){
a=i;
}
};
int main(){
A test;
cout<<test.a;
}
输出:error: no matching function for call to 'A::A()'
其实普通时候,我们定义A test,就是在调用一个空构造函数,等同于A test()。
如果我们没有定义构造函数,编译器会自动写一个空构造函数A::A(),这样就可以调用A test()了。
然而我们已经有一个构造函数了,编译器没有提供空构造函数,因此报错。
再看一个例子,我们看这段代码,会输出什么?是created,main吗?
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
A(){
cout<<"created"<<endl;
}
};
A *test;
int main(){
cout<<"main"<<endl;
test=new A;
}
点我看答案
正确输出是main,created。 只有在new之后,test才被分配内存,调用构造函数。如果没有new,test没有对应的内存,就没有被初始化。我们再看这段代码,又会输出什么?
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
A(){
cout<<"created"<<endl;
}
};
A *test;
int main(){
cout<<"main"<<endl;
test=(A*)malloc(sizeof(A));
}
点我看答案
只输出main。大家可能会很奇怪,不就是把new换成malloc吗?其实,只有new可以自动调用构造函数,malloc不会调用构造函数,因此,我鼓励大家在C++中多使用new而不是malloc。(当然,其实new也有它的缺点,例如不能realloc)析构函数
析构函数的写法和构造函数类似,函数名是类名,只是在前面加上一个~符号,表示析构函数。
在delete一个指针的时候,会自动调用析构函数,与new类似。
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
~A(){
cout<<"destroy,";
}
};
A *test;
int main(){
cout<<"main,";
test=new A;
delete test;
}
通过析构函数,我们可以看出局部变量的作用域。例如,会输出几次destroy?
#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a;
~A(){
cout<<"destroy,";
}
};
int main(){
cout<<"main,";
int n=10;
while(n--){
A test;
}
}
点我看答案
答案:10次,因为while一共实行10次循环,test是局部变量。完。