C++面向对象来源于生活,每个对象都会有初始化设置以及对象销毁前的清理数据的设置
对象的初始化和清理是非常重要的安全问题
构造函数主要用于创造对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用
析构函数主要用于销毁前系统自动调用,执行一些清理工作
构造函数语法:类名()
析构函数语法:~类名()
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();
~student();
};
student::student(){
cout << "构造函数" << endl;
}
student::~student() {
cout << "析构函数" << endl;
}
int main()
{
student stu;
system("pause");
return 0;
}
两种分类方式:
三种调用方式:
调用默认构造的时候不要写括号()系统会默认成是函数的
不要利用拷贝构造函数初始化匿名对象 编译器会认为 类名(p3) ==person p3
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();//无参构造
student(int age);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int age)
{
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
/*括号法*/
student stu1;
student stu2(18);
student stu3(stu2);
system("pause");
return 0;
}
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();//无参构造
student(int age);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int age)
{
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
/*显示法*/
student stu1;
student stu2 = student(18);
student stu3 = student(stu2);
system("pause");
return 0;
}
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();//无参构造
student(int age);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int age)
{
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
/*隐式转换法*/
student stu1;
student stu2 = 10;
student stu3 = stu2;
system("pause");
return 0;
}
匿名对象的意思就是当执行结束后系统立马收回
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();//无参构造
student(int age);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int age)
{
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
/*匿名对象*/
student(1);
system("pause");
return 0;
}
调用时机
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
student();//无参构造
student(int age);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int age)
{
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
void test1(student stu)
{
}
student test2()
{
student stu;
cout << &stu << endl;
return stu;
}
int main()
{
/*使用一个已经创建完毕的对象来初始化一个新对象*/
student stu(18);
student stu1(stu);
/*以值传递的方式给函数传递值*/
test1(stu);
/*以值的方式返回局部对象*/
student stu2 = test2();
cout << &stu2 << endl;
system("pause");
return 0;
}
上面的代码输出的地址也表示了 拷贝构造函数是拷贝一个新的构造函数,所以地址会不同
默认情况下,c++编译器至少给1个类添加3个函数
构造函数调用规则:
下面几张截图就可以充分说明上述构造函数调用规则:
1. 只定义有参构造,声明无参构造会报错 声明拷贝构造不会报错
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
先把代码放上来,然后说一下区别
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
int age;
int *hight;
student();//无参构造
student(int xage,int xhight);//有参构造
student(const student&b);//拷贝构造
~student();
};
student::student()
{
cout << "无参构造" << endl;
}
student::student(int xage, int xhight)
{
age = xage;
hight = new int(xhight);
cout << "有参构造" << endl;
}
student::student(const student&b)
{
cout << "拷贝构造" << endl;
age = b.age;
hight = b.hight;//浅拷贝
hight = new int(*b.hight);//深拷贝
}
student::~student()
{
if (hight != NULL)
{
delete hight;
hight = NULL;
}
cout << "析构函数" << endl;
}
int main()
{
student stu(18, 180);
cout << stu.age << endl;
cout << stu.hight << endl;
student stu1(stu);
cout << stu1.age << endl;
cout << stu1.hight << endl;
system("pause");
return 0;
}
上面代码不可直接使用,在深拷贝和浅拷贝哪里应该要注释一个,现在我来贴出不同情况下运行后的结果
浅拷贝
深拷贝
首先肯定的是,这个代码在浅拷贝的时候运行出错了。首先我们可以看到,拷贝之后的heigh的地址指向的是一样。那么在程序结束的时候,析构函数会delete这个指针,但是由于浅拷贝中hight中2个函数指向的地址一样,所以析构函数相当于delete一个相同的指针2次,那么必然会出错的。
深拷贝是自己在堆区重新开辟的一个新的空间,自然而然2个hight指向的地址不是一个,这个我们打印的结果也看到了,所以在析构函数释放的时候自然不会报错
前面我们写的代码中有参构造,都是在函数内部实现属性和形参的赋值
这个初始化列表作用就是C++提供了初始化列表语法,用来初始化属性
语法:槽函数():属性1(值1)属性2(值2)
传统方式
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
int a, b, c;
student(int xa,int xb,int xc);//有参构造
//student(int xa, int xb, int xc) :a(xa), b(xb), c(xc)
//{}
~student();
};
student::student(int xa, int xb, int xc)
{
a = xa;
b = xb;
c = xc;
cout << "有参构造" << endl;
}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
student stu(1, 2, 3);
cout << stu.a << endl;
cout << stu.b << endl;
cout << stu.c << endl;
system("pause");
return 0;
}
初始化列表
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
int a, b, c;
//student(int xa,int xb,int xc);//有参构造
student(int xa, int xb, int xc) :a(xa), b(xb), c(xc)
{}
~student();
};
//student::student(int xa, int xb, int xc)
//{
// a = xa;
// b = xb;
// c = xc;
// cout << "有参构造" << endl;
//}
student::~student()
{
cout << "析构函数" << endl;
}
int main()
{
student stu(1, 2, 3);
cout << stu.a << endl;
cout << stu.b << endl;
cout << stu.c << endl;
system("pause");
return 0;
}
C++中类的成员可以是另外一个类,我们称改成员为对象成员
当其他类对象作为本类成员,构造时候要先构造对象,在构造自身
析构函数刚好相反
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class phone
{
public:
string phonename;
phone(string a)
{
phonename = a;
cout << "phone 的构造函数" << endl;
}
~phone()
{
cout << "phone 的析构函数" << endl;
}
};
class student
{
public:
string name;
phone phones;
student(string xname, string xphone):name(xname),phones(xphone)
{
cout << "student 的构造函数" << endl;
}
~student()
{
cout << "student 的析构函数" << endl;
}
};
int main()
{
student stu("张三","华为");
system("pause");
return 0;
}
静态成员就是在成员变量和成员函数前加关键字static
静态成员变量
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
static int age;
};
int student::age = 18;
int main()
{
student stu1;
cout << stu1.age << endl;
student stu2;
stu2.age = 20;
cout << stu1.age << endl;
cout << &stu1.age << endl;
cout << &stu2.age << endl;
system("pause");
return 0;
}
访问方式:
类内声明,类外初始化
#include
#include
#include //c++中字符串需要添加这个头文件
#include
using namespace std;
class student
{
public:
static int age;
static void fun1()
{
age = 200;
}
private:
static void fun2()
{
}
};
int student::age = 18;
int main()
{
student stu1;
cout << stu1.age << endl;
student::fun1();
cout << stu1.age << endl;
system("pause");
return 0;
}