构造函数
对于类对象成员的初始化我们始终是建立成员函数然后手工调用该函数对成员进行赋值的,那么在c++中对于类来说有没有更方便的方式能够在对象创建的时候就自动初始化成员变量呢,这一点对操作保护成员是至关重要的,答案是肯定的。关于c++类成员的初始化,有专门的构造函数来进行自动操作而无需要手工调用。
类构造函数,专门用于构造新对象、将值赋给它们的数据成员。
构造函数定义:
1.C++规定,每个类必须有默认的构造函数,没有构造函数就不能创建对象。
2.若没有提供任何构造函数,那么c++自动提供一个默认的构造函数,该默认构造函数是一个没有参数的构造函数,它仅仅负责创建对象而不做任何赋值操作。
3.只要类中提供了任意一个构造函数,那么c++就不在自动提供默认构造函数。为类定义了构造函数后就必须为它提供默认构造函数。
4.类对象的定义和变量的定义类似,使用默认构造函数创建对象的时候,如果创建的是静态或者是全局对象,则对象的位模式全部为0,否则将会是随机的。
首先看一下在没有构造函数的时候,我们需要定义一个初始化成员函数
void Stock::init(const string & co,long n, double pr)
{
company =co;
if (n<0)
{
std::cout<<"Number of shares can't be negative;"
<<company<<"shares set to 0.\n";
shares=0;
}
else
shares=n;
share_val=pr;
}
定义构造函数后,可以直接在构造函数内进行初始化,代码如下:
Stock::Stock(const string & co,long n, double pr)
{
company =co;
if (n<0)
{
std::cout<<"Number of shares can't be negative;"
<<company<<"shares set to 0.\n";
shares=0;
}
else
shares=n;
share_val=pr;
}
两者的定义代码是没有什么区别的,唯一的区别是第一段代码是我们自己定义的初始化函数,我们需要在主函数中再次调用,才能实现数据成员的初始化,而第二段代码,程序在声明对象时,会自动调用。
注意:不要将类成员名称用作构造函数的参数名,为了避免这种混乱,常见做法如下:
(1)使用 m_ 前缀:
class Stock
{
private:
string m_company;
long m_shares;
...
}
(2)使用后缀_:
class Stock
{
private:
string company_;
long shares_;
...
}
两种使用构造函数的方法:
Stock food=Stock("World",100,1.25);
Stock garment("Furry",100,1.25);
如果提供了非默认构造函数(如Stock( const char co,int n,double pr)),但没有提供默认构造函数,则下面的声明将会出错:Stock stock1;
举个例子,看下面的代码:
#include <iostream>
class Stock
{
public:
Stock(char *input_name)//有参数的构造函数
{
name=new char[10];
strcpy(name,input_name);
}
void show();
protected:
char *name;
};
void Stock::show()
{
std::cout<<name<<endl;
}
void main()
{
//Stock stock1;//这里是错误的,因为没有无参数的构造函数
Stock a("test");
a.show();
cin.get();
}
这样做得原因是想禁止创建未初始化对象。就是说如果想要创建对象,而不显示的初始化,则必须定义一个不接受任何参数的默认构造函数。定义默认构造函数的方式有两种。一种是给已有构造函数的所有参数提供默认值:
Stock( const string & co="good",int n=0,double pr=0.0);
另一种方式是通过函数重载来定义另一个构造函数——一个没有参数的构造函数:
Stock();
由于只能有一个默认构造函数,因此不要同时采用者两种方式。使用上述任何一种方式创建默认函数后,便可以声明对象变量,而不对它们显式初始化:
Stock first;//隐式默认构造函数
Stock first=Stock();//显式
Stock *first=new Stock;//隐式
注意如下非默认构造函数:
Stock first("good");//接受参数的构造函数
Stock first();//返回Stock对象的函数
析构函数
一个类可能需要在构造函数内动态分配资源,那么这些动态开辟的资源就需要在对象不复存在之前被销毁掉,那么c++类的析构函数就提供了这个方便。
析构函数的定义:用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将调用一个函数完成清理工作。
如果函数用new来分配,则析构函数使用delete来释放,假设没有使用,new则不需要,但是析构函数是很有用的。假如函数代码缺少析构函数,在程序结束后,动态开辟的内存空间并没有随着程序的结束由析构函数逐一清除被占用的动态堆空间那么就会造成内存泄露,使系统内存不断减少系统效率将大大降低。
析构函数的定义一般是在类名前面加~;
Stock::~Stock()
{
}