asp.net网站建设ppt,中国建造师官网查询,管网建设方案,推动高质量发展的措施目录
构造函数和析构函数
构造函数
析构函数
构造函数的分类及调用
括号法
显示法
隐式转换法
拷贝构造函数的调用时机
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
以值方式返回局部对象
构造函数调用规则
初始化列表
类对象作…目录
构造函数和析构函数
构造函数
析构函数
构造函数的分类及调用
括号法
显示法
隐式转换法
拷贝构造函数的调用时机
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
以值方式返回局部对象
构造函数调用规则
初始化列表
类对象作为其他类成员 各类的构造和析构执行顺序 构造函数和析构函数
构造函数 主要作用在于创建对象时为对象的成员属性赋值构造函数由编译器自动调用无须手动调用。 构造函数语法类名(){} 构造函数没有返回值也不写void函数名称与类名相同构造函数可以有参数因此可以发生重载程序在调用对象时候会自动调用构造无须手动调用,而且只会调用一次
析构函数 主要作用在于对象**销毁前**系统自动调用执行一些清理工作。 析构函数语法~类名(){} 析构函数没有返回值也不写void函数名称与类名相同,在名称前加上符号 ~析构函数不可以有参数因此不可以发生重载程序在对象销毁前会自动调用析构无须手动调用,而且只会调用一次
构造和析构都是必须有的实现如果我们自己不提供编译器会提供一个空实现的构造和析构
class Person {public:/* 构造函数 */Person() {cout 我是构造函数 endl; // 我是构造函数}/* 细狗函数 */~Person() {cout 我是细狗函数 endl; // 我是细狗函数system(pause)在的情况不会执行因为代码还没走完不会去销毁类}
};int main() {class Person zhanghai;system(pause);return 0;
}
构造函数的分类及调用
两种分类方式
按参数分为 有参构造和无参构造默认构造按类型分为 普通构造和拷贝构造
三种调用方式
括号法显示法隐式转换法
括号法
class Person {
public:int age;Person() {cout Person的无参构造函数调用 endl;}Person(int a) {age a;cout Person的有参构造函数调用 endl;}Person(const Person p) { //将传入的人身上的所有属性拷贝到我身上age p.age;cout Person的拷贝构造函数调用 endl;}~Person() {cout Person的细狗函数 endl;}
};class Person p1; // 默认 无参构造函数的调用 调用默认的无参构造时不要加小括号
class Person p2(1); // 有参构造函数的调用
class Person p3(p2); // 拷贝构造函数的调用
cout p2.age endl; // 10
cout p3.age endl; // 10
显示法
class Person {
public:int age;Person() {cout Person的无参构造函数调用 endl;}Person(int a) {age a;cout Person的有参构造函数调用 endl;}Person(const Person p) { //将传入的人身上的所有属性拷贝到我身上age p.age;cout Person的拷贝构造函数调用 endl;}~Person() {cout Person的细狗函数 endl;}
};Person p1;
Person p2 Person(10); // 有参构造
Person p3 Person(p2); // 拷贝构造Person(10); // 匿名对象特点当前行执行结束后系统会立即回收掉匿名对象
cout 我的上一句输出是 Person的细狗函数 endl;
Person(p3); // 不要利用拷贝构造函数初始化对象编辑器会认为 Person(p3) Person p3隐式转换法 class Person {
public:int age;Person() {cout Person的无参构造函数调用 endl;}Person(int a) {age a;cout Person的有参构造函数调用 endl;}Person(const Person p) { //将传入的人身上的所有属性拷贝到我身上age p.age;cout Person的拷贝构造函数调用 endl;}~Person() {cout Person的细狗函数 endl;}
};Person p4 10; // 有参构造 相当于 Person p4 Person(10)
Person p5 p4; // 拷贝构造 相当于 Person p5 Person(p4)
拷贝构造函数的调用时机
C中拷贝构造函数调用时机通常有三种情况
使用一个已经创建完毕的对象来初始化一个新对象值传递的方式给函数参数传值以值方式返回局部对象
使用一个已经创建完毕的对象来初始化一个新对象
class Person {
public:Person() {cout 无参构造函数! endl;mAge 0;}Person(int age) {cout 有参构造函数! endl;mAge age;}Person(const Person p) {cout 拷贝构造函数! endl;mAge p.mAge;}//析构函数在释放内存之前调用~Person() {cout 析构函数! endl;}
public:int mAge;
};void test01() {Person man(100); //p对象已经创建完毕Person newman(man); //调用拷贝构造函数Person newman2 man; //拷贝构造//Person newman3;//newman3 man; //不是调用拷贝构造函数赋值操作
}值传递的方式给函数参数传值
class Person {
public:Person() {cout 无参构造函数! endl;mAge 0;}Person(int age) {cout 有参构造函数! endl;mAge age;}Person(const Person p) {cout 拷贝构造函数! endl;mAge p.mAge;}//析构函数在释放内存之前调用~Person() {cout 析构函数! endl;}
public:int mAge;
};void doWork(Person p1) { //相当于Person p1 p;}
void test02() {Person p; //无参构造函数doWork(p);
}
以值方式返回局部对象
class Person {
public:Person() {cout 无参构造函数! endl;mAge 0;}Person(int age) {cout 有参构造函数! endl;mAge age;}Person(const Person p) {cout 拷贝构造函数! endl;mAge p.mAge;}//析构函数在释放内存之前调用~Person() {cout 析构函数! endl;}
public:int mAge;
};Person doWork2()
{Person p1;cout (int *)p1 endl;return p1; // 返回的是p1的副本跟p1毫无干系只是相同而已
}void test03()
{Person p doWork2(); // Person p p1cout (int *)p endl;
}int main() {/*依次输出无参构造函数ff44aaff拷贝构造函数析构函数ff55aacc析构函数*/test03();return 0;
}
构造函数调用规则
默认情况下c编译器至少给一个类添加3个函数
默认构造函数(无参函数体为空)默认析构函数(无参函数体为空)默认拷贝构造函数对属性进行值拷贝
构造函数调用规则如下 如果用户定义有参构造函数c不在提供默认无参构造但是会提供默认拷贝构造如果用户定义拷贝构造函数c不会再提供其他构造函数、 #include iostream
using namespace std;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;}
public:int age;
};void test01()
{Person p1(18);//如果不写拷贝构造编译器会自动添加拷贝构造并且做浅拷贝操作Person p2(p1);cout p2的年龄为 p2.age endl;
}void test02()
{//如果用户提供有参构造编译器不会提供默认构造会提供拷贝构造Person p1; //此时如果用户自己没有提供默认构造会出错Person p2(10); //用户提供的有参Person p3(p2); //此时如果用户没有提供拷贝构造编译器会提供//如果用户提供拷贝构造编译器不会提供其他构造函数Person p4; //此时如果用户自己没有提供默认构造会出错Person p5(10); //此时如果用户自己没有提供有参会出错Person p6(p5); //用户自己提供拷贝构造
}int main() {/*注释掉 拷贝构造函数 的情况有参构造函数!p2的年龄为 18析构函数!析构函数!*/test01();return 0;
}
初始化列表 C用来初始化属性 ——构造函数()属性1(值1),属性2值2... {} 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 PrintPerson() {cout mA: m_A endl; // 1cout mB: m_B endl; // 2cout mC: m_C endl; // 3}
private:int m_A;int m_B;int m_C;
};int main() {Person p(1, 2, 3);p.PrintPerson();return 0;
}
类对象作为其他类成员 各类的构造和析构执行顺序
构造的顺序是 先调用对象成员的构造再调用本类构造 析构顺序与构造相反 #include iostream
#include string
using namespace std;class Phone
{
public:Phone(string name){m_PhoneName name;cout Phone构造 endl;}~Phone(){cout Phone析构 endl;}string m_PhoneName;};class Person
{
public:// 初始化列表可以告诉编译器调用哪一个构造函数 Phone m_Phone pName Phone m_Phone Phone(pName) 有参构造Person(string name, string pName) :m_Name(name), m_Phone(pName){cout Person构造 endl;}~Person(){cout Person析构 endl;}void playGame(){cout m_Name 使用 m_Phone.m_PhoneName 牌手机! endl;}string m_Name;Phone m_Phone;};
void test01()
{// 当类中成员是其他类对象时我们称该成员为 对象成员// 构造的顺序是 先调用对象成员的构造再调用本类构造// 析构顺序与构造相反Person p(张三, 苹果X);p.playGame();}int main() {test01();return 0;
}