千家信息网

C++的构造和析构实例分析

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,本篇内容主要讲解"C++的构造和析构实例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++的构造和析构实例分析"吧!1. 构造函数1.1 构造函数长
千家信息网最后更新 2025年01月16日C++的构造和析构实例分析

本篇内容主要讲解"C++的构造和析构实例分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++的构造和析构实例分析"吧!

    1. 构造函数

    1.1 构造函数长什么样子

    (1) 函数名和类名相同

    (2) 没有返回值

    (3) 如果不写构造函数,任何类中都存在一个默认的构造函数

    I 默认的构造函数是无参的

    II 当我们自己写了构造函数,默认的构造函数就不存在

    (4) 构造函数在构造对象的时候调用

    (5) delete可以用来删掉默认的函数

    (6) 指定使用默认的无参构造函数,用default说明

    (7) 允许构造函数调用另一个构造函数,只是要用初始化参数列表的写法

    (8) 初始化参数列表 : 只有构造函数有

    I 构造函数名(参数1,参数2,…):成员1(参数1),成员2(参数2),…{}

    II 避免形参名和数据成员名相同的导致问题

    1.2 构造函数干嘛的

    (1) 构造函数用来构造对象

    (2) 构造函数更多是用来初始化数据成员

    1.3 思考

    (1)为什么不写构造函数可以构造对象? 是因为存在一个默认的无参构造函数,所以可以构造无参对象

    (2) 构造函数重载为了什么? 为了构造不同长相的对象。

    #include using namespace std;class MM {public:        //MM() = delete;     删掉默认的构造函数        MM(string mmName, int mmAge)         {                name = mmName;                age = mmAge;                cout << "带参构造函数" << endl;        }        //MM()         //{        //      cout << "无参构造函数" << endl;        //}        MM() = default;  //使用的是默认无参构造函数        void print()         {                cout << name << " " << age << endl;        }protected:        string name="Lisa";        int age=18;};//为了能够构造不同长相的对象,我们会给构造函数缺省处理class Boy{public:        //Boy(string mname="", int mage=19)         //{        //      name = mname;        //      age = mage;        //}        //上面函数 等效可以实现下面三个函数的功能        Boy() {}        Boy(string mName) { name = mName; }        //出错:没有与之匹配的构造函数        Boy(string mName, int mage) { name = mName; age = mage; }protected:        string name;        int age;};//初始化参数列表的写法string girlName = "Baby";class  Student {public:        Student(string mname="", int mage=18) :name(mname), age(mage)         {                cout << "初始化参数列表" << endl;                //继承和类的组合必须采用初始化参数列表写法        }        Student(int mage) :name(girlName), age(mage) {}protected:        string name;        int age;};//构造函数可以调用另一个构造函数初始化数据class TT {public:        TT(string name, int age) :name(name), age(age) {}        //委托构造:允许构造函数调用另一个构造函数        TT():TT("默认",18) {}     //没有给数据初始化        void print()         {                cout << name << "\t" << age << endl;        }protected:        string name;        int age;};int main() {        //MM mm;     构造无参的对象,需要无参构造函数        MM mm("mm", 28);        mm.print();        MM girl;        girl.print();        Boy boy1;        Boy boy2("流浪之子");        Boy boy3("王子", 18);        TT  tt;        tt.print();        return 0;}

    2. 析构函数

    2.1 析构函数长什么样子?

    (1) 无返回值

    (2) 无参数

    (3) 函数名: ~类名

    (4) 不写的话会存在默认的析构函数

    (5) 析构函数不需要自己 调用,对象死亡的之前会调用析构函数

    2.2 析构函数用来干嘛?(什么时候需要自己手动写析构函数)

    (1) 当类中的数据成员是指针,并且动态申请内存就需要手写析构

    (2) 析构函数用来释放数据成员申请动态内存

    3. 拷贝构造函数

    -> 拷贝构造函数也是构造函数,长相和构造函数一样的,只是参数是固定 .拷贝构造函数唯一的参数是对对象引用

    -> 不写拷贝构造函数,也存在一个默认的拷贝构造函数

    -> 拷贝构造函数作用: 通过一个对象去初始化另一个对象

    问题

    I 什么时候调用拷贝构造?

    答:当通过一个对象去创建出来另一个新的对象时候需要调用拷贝

    II 拷贝构造什么时候需要加const修饰参数?

    答:当存在匿名对象赋值操作的时候,必须要const修饰

    #include #include using namespace std;class MM {public:        MM() = default;        MM(string name, int age) :name(name), age(age) {}        void print()         {                cout << name << "\t" << age << endl;        }        //拷贝构造        MM(const MM& mm)                   //MM girl(mm);        {                name = mm.name;  //girl.name=mm.name                age = mm.age;  //girl.age=mm.age                cout << "拷贝构造" << endl;        }protected:        string name;        int age;};void printData(MM mm)   //MM mm=实参;{         mm.print();}void printData2(MM& mm) //不存在拷贝本{        mm.print();}int main() {        MM mm("mm", 18);        mm.print();        //显示调用调用        cout << "显示调用调用" << endl;        MM girl(mm);        //通过一个对象创建另一个对象        girl.print();        //隐式调用        cout << "隐式调用" << endl;        MM girl2 = mm;           //拷贝构造        girl2.print();        MM girl3;        girl3 = mm;                   //运算符重载        girl3.print();                  //函数传参        cout << "第一种调用形态" << endl;        printData(mm);        cout << "第二种调用形态" << endl;        printData2(mm);        //无名对象 匿名对象        MM temp;        temp = MM("匿名", 18);        temp.print();        //匿名对象创建对象时候,拷贝构造一定要用const修饰        MM temp2 = MM("匿名", 199);        return 0;}

    4. 深浅拷贝

    (1)浅拷贝: 默认的拷贝构造叫做浅拷贝

    (2)深拷贝: 拷贝构造函数中做了new内存操作,并且做拷贝赋值的操作

    #include#include #include using namespace std;class MM {public:        MM(const char* mname, int age) :age(age)        {                name = new char[strlen(mname) + 1];                strcpy_s(name, strlen(mname) + 1, mname);        }        void print()         {                cout << name << "\t" << age << endl;        }        MM(const MM& object)         {                //name = object.name;                name = new char[strlen(object.name) + 1];                strcpy_s(name, strlen(object.name) + 1, object.name);                //name = object.name;                age = object.age;        }        ~MM()         {                delete[] name;        }protected:        char* name;        int age;};int main() {        {                MM mm("baby", 19);                MM girl(mm);                MM gm = mm;                mm.print();                girl.print();                gm.print();        }        return 0;}

    5. 构造和析构顺序问题

    (1)普通对象,构造顺序和析构顺序是相反

    (2)new出来的对象,delete会直接调用析构函数

    (3)static对象,当程序关闭的时候,生命周期才结束,所以是最后释放

    #include #include using namespace std;class MM {public:        MM(string name="x") :name(name) {                cout << name;        }        ~MM(){                cout << name;        }protected:        string name;};int main() {        {                MM mm1("A");                     //A                static MM mm2("B");         //B   程序关闭时候才死亡,最后析构                MM* p3 = new MM("C");     //C                MM mm4[4];                         //xxxx                delete p3;                         //C  delete 直接调用析构                p3 = nullptr;                                                                //xxxxAB        }        //ABCxxxxCxxxxAB        return 0;}

    6. C++结构体

    #include #include using namespace std;struct MM {        //默认为公有属性        //类中默认属性是私有属性//protected:        string name;        int age;public:        MM(string name) :name(name)         {                cout << "构造函数" << endl;        }        MM(const MM& object)         {                name = object.name;                age = object.age;                     cout << "拷贝构造" << endl;        }        ~MM()         {        }};int main() {        //采用创建时候赋值的方式,也是调用构造函数        //MM object = { "lisa",19 };  错误,因为没有两个参数的构造函数        MM  object = { "lisa" };        cout << object.name << "\t" << object.age << endl;        //C++结构体一旦写了构造函数,就必须按照C++类的方式的去用        MM mm(object);        cout << mm.name << "\t" << mm.age << endl;        return 0;}

    答疑:

    • 为什么要手动写析构函数? 因为默认的不会释放数据成员动态申请的内存

    • 函数名和类型相同函数叫做构造函数

    • 函数名字是~类名的无参函数叫做析构函数

    • 以对象的引用为参数的构造函数叫做拷贝构造函数(复制构造函数)

    • 怎么写出来,默认的构造函数,就是那种在没有传参的时候的那一串垃圾值

    class Boy{public:        Boy() {}        void print()         {                cout << a << "\t" << b << "\t" << c << endl;        }protected:        int a;        int b;        int c;};int main(){    return 0;}

    到此,相信大家对"C++的构造和析构实例分析"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    函数 对象 拷贝 参数 时候 成员 数据 C++ 内存 实例 实例分析 分析 相同 写法 动态 属性 类名 长相 问题 顺序 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发前景好的工作 中国知网新闻数据库 网络技术与路由交换的区别 关键数据库属于 呼和浩特网络安全培训会 浙江什么软件开发设施价格优惠 数据库技术三级和软考数据库 爬取数据记录在数据库中 face 正在选择服务器 网络技术中关键工作 你还知道哪些网络安全小知识 网络安全技术教程pdf电子书 电脑方舟加服务器为什么进不去 北京刻绘大师软件开发中心 数据库安全控制目标是什么 重庆热创网络技术 会计信息化网络技术的应用 无锡智能软件开发市场价格 陕西定制化服务器厂家推荐 化和网络安全工作要点 浦东新区本地网络技术售后服务 数据库向表中添加字段 数据软件开发设施服务标准 戴尔服务器开机键不亮灯 打造服务器有什么要求 软件开发跟网络营销哪个好 oracle数据库的使用 gassandra数据库 福鼎小程序软件开发 误删mysql数据库表
    0