IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 对象使用优化 -> 正文阅读

[C++知识库]C++ 对象使用优化

对象的生命周期

例子1:

class Test
{
    public:
        Test(int a= 10) :ma(a)
        {   
            cout << "Test()" <<endl;
        }

        ~Test() 
        {
            cout << "~Test()" <<endl;
        }
        Test(const Test &t):ma(t.ma)
        {
            cout << "Test(const Test&)" <<endl;
        }

        Test& operator=(const Test &t)
        {
            cout << "operator=" <<endl;
            ma = t.ma;
            return *this;
        }
    private:
        int ma;

};

int main01()
{
    Test t1; 
    Test t2(t1);
    Test t3 = t1;
    //Test(20) 显示生成临时对象     生存周期:所在的语句
    //Test t4(20); 没有区别的
    /*
        C++编译器对于对象构造的优化:用临时对象生成新对象的时候,临时对象就不产生了,直接构造新的对象
    */
    Test t4 = Test(20);
    cout << "-------------------" <<endl;
    t4 = t2; //operator=
    
    //显示生成临时对象:先生成临时对象,然后调用拷贝构造
    t4 = Test(30);  //Test() operator=  ~Test()
    //隐式生成临时对象,找test中合适的构造函数
    t4 = 30;        //Test() operator=  ~Test()

    cout << "-------------------" <<endl;
    //p指向的是一个已经析构的临时对象,编译没通过,能编译通过也是不安全的
    // Test *p = &Test(40);

    //用 引用 临时量的生命周期不是在当前语句
    const Test &ref = Test(50);

    cout << "-------------------" <<endl;

    return 0;
}

例子2:

class Test01
{
    public:

        Test01(int a = 5,int b =5): ma(a),mb(b)
        {
            cout << "Test01(int,int)" << endl;
        }

        ~Test01()
        {
            cout << "~Test01()" <<endl;
        }

        Test01(const Test01 &src)
            :ma(src.ma),mb(src.mb)
        {
            cout << "Test01(const Test&)" << endl;
        }

        Test01& operator=(const Test01 &src)
        {
            if (this == &src) return *this;
            ma = src.ma;
            mb = src.mb;
            return *this;
        }
    private:
        int ma;
        int mb; 

};

//#1 Test01(int,int)
Test01 t1(10,10); 
//#20 ~Test01()
int main()
{
    //#3 Test01(int,int)
    Test01 t2(20,20); 
    //#17 ~Test01()

    //#4 Test01(const Test&)
    Test01 t3 = t2; 
    //#16 ~Test01()

    //t4 编译时期静态变量的内存已存在,但是这个对象也是在运行的时候在构造的
    //static Test01 t4(30,30) 这句和下句是一样的
    //#5 Test01(int,int)
    static Test01 t4 = Test01(30,30);
    //#18 ~Test01()

    //#6 Test01(int,int) operator=  ~Test01()
    t2 = Test01(40,40); 

    //#7 Test01(int,int) operator= ~Test01()
    t2 = (Test01)(50,45); //(50,50) = (Test01)45;  ==> Test01(int);

    //#8 Test01(int) operator= ~Test01()
    t2 = 60; 

    //#9  Test01(int,int) 
    Test01 *p1 = new Test01(70,70);

    //#10 Test01(int,int)  Test01(int,int) 
    Test01 *p2 = new Test01[2];

    // Test01 *p3 = &Test01(80,80); //错误的

    //#12 Test01(int,int)
    const Test01 &p4 = Test01(90,90);
    //#15  ~Test01()
    
    //#13 ~Test01()
    delete p1; 

    //#14 ~Test01()  ~Test01()
    delete []p2;
    return 0;
}
//#2 Test01(int,int)
Test01 t5(100,100); 
//#19 ~Test01()

?函数调用的对象参数

class Test
{
    public:
        Test(int data = 10): ma(data)
        {
            cout << "Test(int)" << endl;
        }
        ~Test()
        {
            cout << "~Test(int)" << endl;
        }

        Test(const Test &t):ma(t.ma)
        {
            cout << "Test(const Test&)" <<endl;
        }

        Test& operator=(const Test &t)
        {
            if (this == &t) return *this; 
            cout << "operator = " << endl;
            ma = t.ma;
            return *this;
        }

        int getData() const 
        {
            return ma;
        }

    private:
        int ma;
};

//注意不要返回局部变量,不过static 存放的数据段不一样,static编译时期就分配好内存的,所以该函数生命周期结束对static并没有影响
/*
函数调用,实参传递给行参是拷贝构造,也算是初始化
    1.两个都存在的对象叫赋值
    2.初始化是有一个是新建的对象
    很明显调用过程Test Getobject(Test t) 是 ==》Test t = t1;
*/
Test Getobject(Test t) //按值传递
{
    int val = t.getData();
    Test tmp(val);
    //这一步:临时量到寄存器带出去  所需操作 Test(const Test &) 函数结束再析构
    return tmp; 
}

int main()
{
    Test t1;
    Test t2;
    t2 = Getobject(t1);
    return 0;
}

对象调用的三条优化规则

1.函数参数传递过程中,对象优先按引用传递, 不要按值传递

? ? ? ? 值传递【Test Getobject(Test t)】:会重新初始化(拷贝构造成)另一个对象,函数结束还有析构

? ? ? ? 引用传递【Test Getobject(Test &t)】:会把实参地址传进来,就不会重新初始化另一个对象,也不用再析构

2.函数返回对象的时候,应该优先返回一个临时对象,而不要返回一个定义过的对象

3.接收返回值是对象的函数调用的时候,优先按初始化的方式接收,不要按赋值的方式接收

Test Getobject(Test &t)
{
    int val = t.getData();
    //Test t = Test(val); 
    //等于 是 Test t(val);也就是直接返回临时对象就不会产生临时对象
    return Test(val);
}

int main()
{
    Test t1;
    //等于是 Test t2 = 临时对象;
    Test t2 = Getobject(t1);
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:38:58  更:2022-01-24 10:41:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:42:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码