c++基础--对象初始化和清理(构造函数与析构函数)
构造函数与析构函数
完成对象的初始化与清理
1.构造函数
/*
*构造函数的分类及调用
* 按照参数分类 无参构造(默认) 和有参构造
* 按照类型分类 普通构造和拷贝构造
*/
class person {
public:
int age;
string name;
//无参构造
person() {
cout << "构造函数调用" << endl;
}
//有参构造
person(int a) {
age = a;
cout << "有参构造" << endl;
}
//拷贝构造函数
person(const person& p) {
cout << "拷贝构造" << endl;
age = p.age;
}
//析构函数
~person()
{
cout << "析构函数调用" << endl;
}
};
//构造函数调用(1.括号法 2.显示法 3.隐式转换)
//1.括号法
void test1(){
person p1; //默认构造函数调用
person p2(20);//有参构造
person p3(p2);//拷贝构造函数调用
//注意事项:默认参数不要加括号。例如person p1() 编译器会认为是一个函数声明
cout<<"年龄是:"<<p2.age<<endl;
cout<<"年龄是:"<<p3.age<<endl;
}
//2.显示法
void test2(){
person p2=person(10);
person p3=person(p2);
}
//person (10) 匿名对象
//注意事项 不要利用拷贝构造函数初始化一个匿名对象
//person (p3)=person p3 重定义
//3.隐式转换
void test3(){
person p1=10;//person p1=person (10)
person p2=p1;//person p2=person (p1)
}
2.拷贝构造函数调用时机
class person
{
public:
person() {
cout << "构造函数调用" << endl;
}
person(int a) {
age = a;
cout << "有参构造" << endl;
}
person(const person &p)
{
age = p.age;
cout << "拷贝函数调用" << endl;
}
~person() {
cout << "析构函数调用" << endl;
}
int age;
};
//1.使用一个已经创建完毕的对象来初始化一个新对象
void test1() {
person p1(20);
person p2(p1);
person p3=p1;
cout << p2.age << endl;
};
//2.值传递的方式给函数传值
void dow(person p) {
}
void test2() {
person p3;
dow(p3);
}
//3.值方式返回局部对象
person dow2() {
person p4;
cout << (int*)&p4 << endl;
return p4;
}
void test3() {
person p = dow2();
cout << (int*)&p << endl;
}
3.构造函数调用
调用规则 :
-
默认情况下,c++编译器给一个类至少提供三个函数:
默认构造参数(无参,函数体为空)
默认析构函数(无参,函数体为空)
拷贝构造函数
-
提供有参构造函数之后,不再提供默认构造函数,依然提供拷贝构造函数。
-
提供拷贝构造函数后,其他的不提供。
class person{
public:
person(){
cout<<"默认构造函数调用"<<endl;
}
person(int age){
m_age=age;
cout<<"有参构造函数调用"<<endl;
}
person(const person &p){
m_age=p.m_age;
cout<<"拷贝构造函数调用"<<endl;
}
~person(){
cout<<"析构函数调用"<<endl;
}
int m_age;
}
void test01(){
person p;//只提供有参构造后,错误
}
int main(){
system("pasue");
return 0;
}
4.深拷贝和浅拷贝
浅拷贝:简单的赋值拷贝操作 浅拷贝堆区内存重复释放非法操作
深拷贝:在堆区重新申请空间,进行拷贝操作
class person {
public:
person() {
cout << "构造函数调用" << endl;
}
person(int age,int height) {
cout << "有参构造函数调用" << endl;
m_age = age;
m_height = new int(height);
//new开辟的是堆区 需要用指针接受
}
//深拷贝
person(const person& p) {
cout << "拷贝构造函数调用" << endl;
m_age = p.m_age;
//m_height = p.m_height;编译器默认实现
m_height = new int(*p.m_height);
}
~person() {
//析构代码 将堆区开辟数据做释放操作
if (m_height != NULL) {
delete m_height;
m_height = NULL;
}
cout << "析构函数调用" << endl;
}
int m_age;
int* m_height;
};
void test01() {
person p1(18,20);
cout << "p1的年龄:" <<p1.m_age<<"身高:"<<*p1.m_height << endl;
person p2(p1);
cout << "p2的年龄是:" << p2.m_age <<"身高:"<<*p2.m_height << endl;
}
5.初始化列表
初始化列表和构造函数都是实现对象初始化
class person {
public:
//传统初始化方式
person(int a,int b,int c) {
m_a = a;
m_b = b;
m_c = c;
}
//初始化列表
person(int a, int b, int c) :m_a (a), m_b (b), m_c (c){}
void print() {
cout << m_a << endl;
}
int m_a;
int m_b;
int m_c;
};
6.类对象作为成员
先构造其他类,再构造自己
class phone {
public:
phone(string name) {
p_name = name;
cout << "phone的构造函数调用" << endl;
}
~phone() {
cout << "phone的析构函数" << endl;
}
string p_name;
};
class person {
public:
//初始化列表
person(string name, string p_name) :m_name(name),p_name(p_name)
{
cout << "person的构造函数调用" << endl;
}
~person() {
cout << "person的析构函数" << endl;
}
string m_name;
phone p_name;
};
//当其他类的对象作为本类的成员,先构造其他类对象,再构造自身
//析构函数与构造函数相反
void test() {
person p("张三","华为");
cout << p.m_name << p.p_name.p_name<< endl;
}
7.静态成员函数
//静态成员函数
//所有对象共享一个函数
//静态成员函数只能访问静态成员变量
class person {
public:
static void fun() {
m_a = 100;
//m_b = 10;不可访问非静态变量
cout << m_a << endl;
}
//静态成员变量
static int m_a;//声明但是未定义
int m_b;
private://静态成员函数也有访问权限
int m_c;
};
//类外显示定义,不需要写static
int person::m_a = 10;//定义同时初始化

浙公网安备 33010602011771号