首先我们看下一个简单的类:
#include <iostream>
class Entity
{
public:
float X, Y;
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
int main()
{
Entity e;
e.Print();
std::cin.get();
}
输出结果如下:
这个很奇怪的数字,实际上就是系统随机分配的数,因为我们还没有对X和Y进行初始化,而在C++中,不进行初始化的变量是不能使用的,如下:
#include <iostream>
class Entity
{
public:
float X, Y;
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
int main()
{
Entity e;
std::cout << e.X << "," << e.Y << std::endl;
e.Print();
std::cin.get();
}
会报错“error C4700: uninitialized local variable ‘e’ used”,虽然X和Y是public
,而且e也已经被实例化了,但是未初始化的变量还是不能使用。
这时,我们可以定义一个初始化函数Init():
#include <iostream>
class Entity
{
public:
float X, Y;
void Init()
{
X = 0;
Y = 0;
}
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
int main()
{
Entity e;
e.Init();
std::cout << e.X << "," << e.Y << std::endl;
e.Print();
std::cin.get();
}
输出结果为:
但是我们会想,如果每次实例化之后都要写一行初始化函数的代码,是不是太麻烦了?
Entity e1;
e1.Init();
Entity e2;
e2.Init();
Entity e3;
e3.Init();
这时候,构造函数就派上用场了,使用它可以更方便地进行初始化:
#include <iostream>
class Entity
{
public:
float X, Y;
Entity()
{
X = 0;
Y = 0;
}
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
int main()
{
Entity e;
std::cout << e.X << "," << e.Y << std::endl;
e.Print();
std::cin.get();
}
只需要写一个与类名相同的函数作为初始化函数,这样每次实例化的时候就会自动调用这个函数,省去了写调用函数代码的功夫。
与其他函数一样,你也可以向构造函数传入参数:
#include <iostream>
class Entity
{
public:
float X, Y;
Entity(float x, float y)
{
X = x;
Y = y;
}
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
int main()
{
Entity e(1.5, 2.5);
std::cout << e.X << "," << e.Y << std::endl;
e.Print();
std::cin.get();
}
输出结果如下:
有构造函数,就有相反操作的析构函数。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。例子如下:
#include <iostream>
class Entity
{
public:
float X, Y;
Entity()
{
std::cout << "Entity is constructed!" << std::endl;
}
~Entity()
{
std::cout << "Entity is destructed!" << std::endl;
}
};
void Function()
{
Entity e;
}
int main()
{
Function();
std::cin.get();
}
如果在main函数中实例化Entity,构造函数和析构函数的输出要在main函数退出时才能看到,而此时程序也退出了,所以使用一个Function,在其中进行实例化,结果如图: