C++的构造和析构函数
一、构造函数
1、构造函数是在创建对象时自动调用的对象,在整个对象的生命周期里,一定会被调用一次且只能被调用一次(不包括被强制调用)。
2、在构造函数中可以负责对成员变量的初始化、分配资源、设置对象的初始状态。
3、构造函数可以有多个版本,这些不同的版本之间会构造重载,创建对象时的方式不同、给的参数不同会调用相应的构造函数,如果调用的构造函数不存在可能会造成编译错误。
4、如果类中没有定义构造函数,编译器会自动生成一个无参的构造函数,当自定义了一个其他版本的构造函数,则系统默认的无参函数就不会再生成。但是为了防止无参方式创建对象时出错,建议设置2个构造函数。
5、无参构造未必无参,在C++中函数可以有默认参数,如果有参构造全部设置了默认参数,就会和无参构造有冲突,他们2个只能有一个存在。
6、拷贝构造函数是一种特殊的构造函数,就是用一个已有的对象去构造其同类的副本对象,就是对象克隆。
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; class Student { char name[20]; char sex; short age; public: Student (const char* _name,char _sex,short _age) { if(strlen(_name)<20) { strcpy(name,_name); } sex = _sex; age = _age; } Student(Student& that) { strcpy(name,that.name); sex = that.sex; age = that.age; cout << "我被调用了" <<endl; } void show(void) { cout <<name <<" "<<sex <<" "<< age<<endl; } }; int main() { Student stu1("hehe",'m',17); Student stu2 =stu1; stu2.show(); }
7、同样的,编译器也会默认生成一个拷贝构造函数,编译生成的拷贝构造函数默认会逐字节的复制类中的每一个成员。如果在类A中有类B的成员,那么在类A的拷贝构造函数中会自动调用类B的拷贝构造函数。
8、程序员可以自定义拷贝构造来取代默认的拷贝构造,一旦自定义拷贝构造函数,那么编译器就不再生成,并且拷贝构造函数和构造函数不同的是,拷贝构造是只能有一个的,不能重载。
9、一般情况下编译器生成的拷贝构造完全是够用的,不需要自定义拷贝构造函数。
10、赋值构造函数就是一个对象给另一个对象赋值的时候调用的函数,与拷贝构造不同的是,对象A和B都是已经构造完成 的,此时要做的是讲B =A;而拷贝构造是需要对象A去创建对象B的。
#include <iostream> #include <string.h> using namespace std; class Student { char* name; char sex; short age; public: Student(const char* _name="",char sex='f',short age=1):sex(sex),age(age) { name = new char[strlen(_name)+1]; strcpy(name,_name); } Student(const Student& that) { name = new char[strlen(that.name)+1]; strcpy(name,that.name); sex = that.sex; age = that.age; } void show(void) { cout << name << " " << age << endl; } void addAge(void) const { age++; } void operator = (Student& that) { if(this == &that) return; delete[] name; name = new char[strlen(that.name)+1]; strcpy(name,that.name); sex = that.sex; age = that.age; } ~Student(void) { delete[] name; } }; int main() { Student s1("lili",'m',33); s1.show(); Student s2 = s1; s2.show(); s2.addAge(); s2.show(); s2 = s1; s2.show(); }
11、同样的编译器也会默认生成赋值构造函数,一般情况下默认的赋值构造也是基本够用的,除非有成员是指针,指向了额外的内存空间,这种情况我们才需要自定义拷贝构造函数和赋值构造函数。
1、当对象被销毁时自动调用的函数叫析构函数,对象的整个生命周期中只能被调用一次,它是对象被销毁前的最后一个执行的动作。
class 类名
{
// 不能重载、只能有一个
~类名(void)
{
}
}