神秘的临时对象(十八)-创新互联

    我们在程序中不可避免的会遇到临时变量,那么在 C++ 中也会不可避免的会遇到临时对象。我们以代码为例来进行分析

创新互联专业为企业提供和布克赛尔蒙古网站建设、和布克赛尔蒙古做网站、和布克赛尔蒙古网站设计、和布克赛尔蒙古网站制作等企业网站建设、网页设计与制作、和布克赛尔蒙古企业网站模板建站服务,10余年和布克赛尔蒙古做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
#include 

class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
    }
    
    Test()
    {
        Test(0);
    }
    
    void print()
    {
        printf("mi = %d\n", mi);
    }
};

int main()
{
    Test t;
    
    t.print();
    
    return 0;
}

        我们这段代码是想要在 Test() 中以 0 作为参数调用 Test(int i),然后将成员变量 mi 初始化为 0,最后想要打印它的值。我们来看看编译结果

神秘的临时对象(十八)

        我们看到打印的是一个随机数,并不是我们所期望的 0。那这到底是怎么回事呢?那么我们想下:构造函数既然是一个特殊的函数。那么它是否可以直接调用呢?是否可以在构造函数中调用构造函数呢?直接调用构造函数的行为是什么?我们就直接说答案了。直接调用构造函数将产生一个临时对象,临时对象的生命周期只有一条语句的时间,临时对象的作用域只在一条语句中,临时对象是 C++ 中值得警惕的灰色地带!上面那个程序也就是说第 15 行的调用的构造函数会产生临时对象,它的生命周期只有那一行的时间,所以在后面我们打印出来的才会是一个随机值。

        下面我们在上面程序的基础上进行修改,代码如下

#include 

class Test
{
private:
    int mi;
    
    void init(int i)
    {
        mi = i;
    }
public:
    Test()
    {
        init(0);
    }
    
    void print()
    {
        printf("mi = %d\n", mi);
    }
};

int main()
{
    Test t;
    
    t.print();
    
    return 0;
}

        我们再次编译看看结果

神秘的临时对象(十八)

        这次我们看到它按照我们所想要的初始化为 0 了。现代的 C++ 编译器在不影响最终执行结果的前提下,会尽力减少临时对象的产生!!!

        我们再来看一个示例代码

#include 

class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
        printf("Test(int i): %d\n", mi);
    }
    Test(const Test& obj)
    {
        mi = obj.mi;
        printf("Test(const Test& obj): %d\n", mi);
    }
    Test()
    {
        mi = 0;
        printf("Test()\n");
    }
    void print()
    {
        printf("mi = %d\n", mi);
    }
    ~Test()
    {
        printf("~Test()\n");
    }
};

Test func()
{
    return Test(50);
}

int main()
{
    Test t = Test(10);
    Test tt = func();
    
    t.print();
    tt.print();
    
    return 0;
}

        我们看到在第 40 行定义了 Test 对象 t,并将它初始化为 10。按照我们想的它在这块先是生成一个临时对象初始化为 10 并将这个临时对象赋值给对象 t。所以这块可能会牵扯到拷贝构造函数。第 41 行也是这样的,先是在 func 函数中生成一个临时对象 Test(50),并将它赋值给对象 tt。所以也会牵扯到拷贝构造函数。那么我们来编译下看看结果

神秘的临时对象(十八)

        我们看到并没有打印出拷贝构造函数的身影。再回想下我们之前讲的,现代编译器已经大大优化了,尽量会避免临时对象的产生。那么第 40 行将会等价于 Test t(10),第 41 行将会等价于 Test tt = Test(50) ==> Test tt(50);所以这样也就能解释清楚了,它确实没牵扯到拷贝构造函数。我们得随时注意 C++ 中的临时对象,因为它将会导致一些莫名其妙的结果。通过对临时对象的学习,总结如下:1、直接调用构造函数将产生一个临时对象,临时对象是性能的瓶颈,也是 bug 的来源之一;2、现代 C++ 编译器会尽力避开临时对象,实际工程开发中需要人为的避开临时对象。

        欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站名称:神秘的临时对象(十八)-创新互联
当前网址:http://pwwzsj.com/article/dsppoj.html