析构函数与构造函数的使用
-
构造函数的引入:每个类的设计者可能都会按照自己的习惯设计一个用初始化数据成员的函数,如果每个类都有自己特定的初始化方法,用户在使用时就不方便。由于类定义对象后,都需要进行初始化,设计者可以设计统一的接口来完成初始化。这个统一的接口就是将对象初始化的工作统一交给类的构造函数来完成。
-
构造函数的定义格式:<类名>: :<类名>(参数列表)
-
构造函数的特殊性质:
a.构造函数的函数名与类名相同
b.构造函数没有返回值。有参数列表可以重载
c.构造函数时类的公有成员,在定义对象时由编译系统自动调用,其他时候无法调用。因此构造函数只能一次性的影响对象成员的初值 -
析构函数:在对象生存期结束后由编译系统自动调用完成一些清理工作、、
-
析构函数的定义格式:<类名>: : ~<类名>()
-
构造函数的特殊性质:
a.析构函数没有返回值
b.它的形参表中没有任何参数,因此不能重载
#include <iostream>
using namespace std;
/*构造函数与析构函数*/
class Book{
private:
char *bookName;
char *author;
float price;
public:
void print();
//构造函数与类名一致,不指定返回类型
Book(const char *bookName1,const char *author1,float price1);
~Book(); //析构函数,在对象生存期结束时由编译系统自动调用我们定义的析构函数完成清理工作
};
int main()
{
//定义一个对象的时候,编译系统会自动调用我们定义的构造函数来初始化数据,不需要再显示调用
Book book("《平凡的世界》","路遥",98.20);
book.print();
return 0;
}
//成员函数直接访问内部私有的数据成员
void Book::print()
{
cout<<bookName<<'\t'<<author<<'\t'<<price<<endl;
}
//构造函数,初始化数据成员的值
Book::Book(const char *bookName1,const char *author1,float price1)
{
//这里如果不加const运行后会出现警告:不建议使用从字符串常量到‘char*’的转换[-Wwrite-strings]
//原因是编译构造函数的时候默认传来不可修改的串,所以需要加上const
bookName=new char[strlen(bookName1)+1]; //len+1是因为字符串以'\0'结束
author=new char[strlen(author1)+1];
strcpy(bookName,bookName1);
strcpy(author,author1);
price=price1;
}
Book::~Book()
{
delete [] bookName;
delete [] author;
}
构造函数与析构函数的执行顺序
#include <iostream>
using namespace std;
class Student{
private:
string name;
int num;
public:
Student(string name1,int num1)
{
name=name1;
num=num1;
cout<<name<<'\t';
//cout<<"structor called"<<endl;
}
~Student()
{
cout<<num<<'\t';
//cout<<"destructor called"<<endl;
}
};
int main()
{
//对象先声明的先执行构造函数
//而析构函数的执行次序与之相反
Student std1("熊一",1);
Student std2("熊二",2);
Student std3("张三",3);
Student std4("李四",4);
Student std5("王五",5);
return 0;
}