构造函数
函数名必须和类名完全相同,没有返回类型,当对象被创建时有系统自动调用,设置对象的初始状态。
- C++规定,每个类必须有默认的构造函数,没有构造函数就不能创建对象。
- 若没有提供任何构造函数,那么c++提供自动提供一个默认的构造函数,该默认构造函数是一个没有参数的构造函数,它仅仅负责创建对象而不做任何赋值操作。
- 只要类中提供了任意一个构造函数,那么c++就不在自动提供默认构造函数。
- 类对象的定义和变量的定义类似,使用默认构造函数创建对象的时候,如果创建的是静态或者是全局对象,则对象的位模式全部为0,否则将会是随机的。
默认构造函数(缺省构造函数)
可以不带任何参数构造对象,表示对象默认(缺省)状态。如果有参构造函数的所有参数都带有默认值,那么该构造函数就也可以被当做默认构造函数。
默认构造函数(缺省构造函数)跟系统提供不提供构造函数没有任何关系,默认构造函数就是当你定义一个对象时不需要提供初始化的的构造函数。
包括三种情况:
- 根本没有显式的定义构造函数,当然由系统提供的默认构造函数,这个构造函数没有参数,啥也不做
- 定义了构造函数,但是不带任何参数,这也叫默认构造函数,特别的,如果这个函数体什么都不执行,就跟情况1一样。
- 定义了构造函数,也带有参数,但是所有参数都有默认参数,这个也叫默认构造函数。
A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter). A type with a public default constructor is DefaultConstructible.
来源:http://en.cppreference.com/w/cpp/language/default_constructor
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默认构造函数
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
};
转换构造函数
可以通过单个参数调用的构造函数,从参数的类型隐式转换为所构造对象的类型。通过explicit关键字可以强制通过这样的构造函数所进行的类型转换必须显式完成。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默认构造函数
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//带参构造函数
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
};
拷贝构造函数(复制构造函数)
以所构造对象类型的(常)引用为唯一调用参数的构造函数,实现同类型对象的克隆,即构造对象的副本。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默认构造函数
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//带参构造函数
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷贝构造函数
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
};
析构函数
析构函数在对象被销毁时自动调用。对于局部对象而言,就是在它离开作用域时,对于堆对象而言,delete/delete[]负责调用析构函数。析构函数通常负责在对象被销毁之前,释放其动态分配的资源。
析构函数不能重载。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默认构造函数
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//带参构造函数
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷贝构造函数
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
//析构函数
~Student (void)
{
//这里不能这样写,C++中内置类型不需要delete/delete[]
//delete m_id, m_name[20], m_age; //error
cout << "~这是析构函数~" << endl;
}
};
构造和析构的顺序:
当一个对象被构造时,先执行成员子对象的构造函数,后执行该对象的构造代码。如果函数多个成员子对象,按照其被声明的顺序依次构造。析构的顺序和构造严格相反。
最后奉上程序完整代码:
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默认构造函数
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//带参构造函数
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷贝构造函数
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
//析构函数
~Student (void)
{
//这里不能这样写,C++中内置类型不需要delete/delete[]
//delete m_id, m_name[20], m_age; //error
cout << "~这是析构函数~" << endl;
}
void show(void)
{
cout << "学号:" << m_id << "\t" << "姓名:" << m_name << "\t" << "年龄:" << m_age << endl;
}
};
int main(int argc, const char * argv[]) {
Student stu1 (1001, "王二", 17);
stu1.show();
Student stu2 (1002, "大许", 17);
stu2.show();
Student stu3 (1003, "邢红", 16);
stu3.show();
return 0;
}