1.构造函数和析构函数
对象的初始化和清理非常重要
构造函数和析构函数是编译器自动调用的,如果我们自己不设置,编译器强制实现。
注意:编译器这两个函数是空实现。即自己写了就用我们写的函数。
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
析构函数:主要作用在于对象销毁前系统自动调用,系统进行一些清理活动。
构造函数 语法:类名(){}
1.没有返回值,也不写void
2.函数名称与类名相同
3.构造函数有参数,因此可以发生重载
4.程序在调用构造时会自动调用,无须手动调用,且只会调用一次
析构函数 语法:~类名(){}
1.没有返回值,也不写void
2.函数名称与类名相同,前面加上符号~
3.析构函数不可以有参数,所以不可以重载
4.程序在对象销毁会自动调用,无须手动调用,且只会调用一次
class person
{
public:
person()
{
cout << "构造函数调用" << endl;
}
~person()
{
cout << "析构函数调用" << endl;
}
};
void test1()
{
person p; //这里只是创建了一个对象,还没调用
}
int main() //类外
{
test1(); //说明构造,析构函数是自动调用的
person p; //在test1中函数调用完就释放。而主函数中的p在按下任意键后才会被销毁
system("pause");
return 0;
}
2.构造函数的分类及调用
两种分类方式:
按参数分:有参构造和无参构造
按类型分:普通构造和拷贝构造
三种调用方式:
括号法
显示法
隐式转换法
注意:
(1)调用默认构造函数时不要加()
(2)不要利用拷贝函数初始化匿名对象
如person(p3);会报错 因为编译器把person(p3) 等价于 person p3 重复构造对象。
class person
{
public:
person()
{
cout << "无参构造函数调用" << endl;
}
person(int a)
{
age = a;//相当于对年龄初始化
cout << "有参构造函数调用" << endl;
}
//拷贝构造函数
person(const person &p) //用当前类名创造一个参数,用引用的形式,再加上const限制修改类中属性
//目的是复制个一模一样的数据
{
age = p.age;//谁调用这个拷贝函数,就把传入的数据拷贝到当前类的属性上
cout << "拷贝构造函数调用" << endl;
}
int age;
};
void test1()
{
括号法
//person p1; //默认构造函数的调用
person p1();编译器会认为这是个函数声明,没有实例化一个对象
//person p2(10); //有参构造函数的调用
拷贝构造函数的调用
//person p3(p2); //拷贝函数的格式,代表将p2的数据复制到p3里
//cout << p3.age << endl; // 此时p2的年龄已被拷贝到p3里
//显示法
person p1;
person p2 = person(10); //表明要传输一个10给构造函数中的a
//显示法拷贝构造函数
person p3 = person(p2); //显示法语法
person(20); //为匿名对象,这也是个对象。当前行执行结束系统就回收
//隐式转换法
person p4 = 30; //相当于person p4 = person(30) 有参构造
person p5 = p4;//拷贝构造
}
int main()
{
test1();
system("pause");
return 0;
}
3.构造函数调用时机
三种情况
(1)使用一个已经创建完毕的对象来初始化一个新对象
(2)值传递的方式给函数参数传值
(3)以值方式返回局部对象(有不懂的看视频p108)
class person
{
public:
person()
{
cout << "无参构造函数调用" << endl;
}
person(int a)
{
m_age = a;
cout << "有参构造函数调用" << endl;
}
//拷贝构造函数
person(const person &p)
{
m_age = p.m_age;
cout << "拷贝构造函数调用" << endl;
}
int m_age;
};
void test1()
{
person p1(20);
person p2(p1);
}
//2.以值传递的方式调用拷贝函数
void zhi(person p)
{
int a = p.m_age;
cout << a << endl;
}
void test2()
{
person p(20);
zhi(p); //值传递就是复制一份再传输。这里是把对象p的所有属性传输到zhi函数中 //所以相当于用了拷贝函数
}
//3.值方式返回局部对象
person work() //实参不能返回,所以要按照这个对象拷贝一个新的对象给test03(),再返回
{
person p1; //这个p1执行完以后就释放了
return p1;
}
void test03()
{
person p = work(); //此处编译器已优化,观察不到拷贝现象
//此处的p不等同于p1,两个是不同对象。p1先复制一个,再释放。然后复制的给了p
//所以p和p1的地址也不相同
}
int main()
{
//test2();
test03();
system("pause");
return 0;
}