类的构造函数
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
下面的实例有助于更好地理解构造函数的概念:
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created
Length of line : 6
带参数的构造函数
默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(double len); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line(10.0);
// 获取默认设置的长度
cout << "Length of line : " << line.getLength() <<endl;
// 再次设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created, length = 10
Length of line : 10
Length of line : 6
带参数的构造函数
默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(double len); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line(10.0);
// 获取默认设置的长度
cout << "Length of line : " << line.getLength() <<endl;
// 再次设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created, length = 10
Length of line : 10
Length of line : 6
使用初始化列表来初始化字段
Line::Line( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}
上面的语法等同于如下语法:
Line::Line( double len)
{
length = len;
cout << "Object is being created, length = " << len << endl;
}
假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:
C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
....
}
赋值初始化放在这里可以方便程序人员理解
类的析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
下面的实例有助于更好地理解析构函数的概念:
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数声明
~Line(); // 这是析构函数声明
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;
// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Object is being created
Length of line : 6
Object is being deleted
构造函数的作用:
创建并初始化对象,即对象成员变量赋初始值。
1、构造函数名与类名相同。
2、构造函数没有返回值。
3、构造函数不可以被直接调用。
4、定义了类没有定义构造函数时C++会提供默认构造函数,默认构造函数是无参构造函数,仅负责创建对象。
5、一个类可以有多个构造函数。
6、构造函数不可以是虚函数。原因:虚函数通过基类指针或引用来调用派生类的成员,调用前对象必须存在,然而构造函数就是用来创建对象的。
析构函数的作用:
销毁对象。
特点:
1、析构函数名与类名同名,但须在函数名前加~。
2、析构函数无返回值。
3、析构函数无参数。
4、一个类只能有一个析构函数。
5、析构函数不能重载。
6、如果用户没有编写析构函数,C++会自动提供一个默认的析构函数,这个析构函数不进行任何操作。
7、基类的析构函数常常是虚析构函数。原因:为了避免内存泄漏。
8、析构函数默认不是虚函数。
构造函数与析构函数的调用时机
构造函数和析构函数的调用都是自动的。创建对象时调用构造函数,销毁对象时调用析构函数。
全局对象的构造函数在main函数之前调用,析构函数在main函数执行结束之后调用。不同全局变量的构造函数的执行顺序与变量定义的顺序一致,而析构函数的调用顺序正好相反。
局部变量的构造函数在程序执行到定义局部变量的语句时调用,在退出包含定义局部变量的语句的块时调用析构函数。不同局部变量的构造函数的执行顺序与变量定义的顺序一致,而析构函数的调用顺序正好相反。
静态局部变量的构造函数在程序第一次执行,到定义静态局部变量的语句时调用,而析构函数在main函数执行结束之后调用,不同静态局部变量的构造函数的执行顺序与变量定义的顺序一致,而析构函数的调用顺序正好相反。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base()" << endl;
}
~Base()
{
cout << "~Base()" << endl;
}
};
class Base1:public Base
{
public:
Base1()
{
cout << "Base1()" << endl;
}
~Base1()
{
cout << "~Base1()" << endl;
}
};
class Base2 :public Base
{
public:
Base2()
{
cout << "Base2()" << endl;
}
~Base2()
{
cout << "~Base2()" << endl;
}
};
class Base3 :public Base1,Base2
{
public:
Base3()
{
cout << "Base3()"<<"\n" << endl;
}
~Base3()
{
cout <<"\n"<< "~Base3()" << endl;
}
};
void test()
{
Base3 b;
}
int main()
{
test();
system("pause");
return 0;
}
能看出不同全局变量的构造函数的执行顺序与变量定义的顺序一致,而析构函数的调用顺序正好相反。