zoukankan      html  css  js  c++  java
  • 程序的转化 & 明确的初始化操作 & 参数的初始化 & 返回值的初始化

    一丶程序的转化
    考察以下代码:

    1 X Foo()
    2 {
    3     X xx;
    4     //...
    5     return xx;
    6 }

    看到这个, 你可能会有两个想法:
    1. 每次 Foo() 被调用, 就会传回 xx 的值.
    2. 如果 class X 定义了一个 copy constructor, 那么当 Foo() 被调用时, 保证该 copy constructor 也会被调用.

    这两个假设的真实性实际都要以 class X 如何定义而定, 在一个高品质的 C++ 编译器中, 以上两个假设都是错误的.

    二丶明确的初始化操作
    考察以下代码:

    X x0;
    void FooBar()
    { 
        X x1(x0); 
        X x2 = x0; 
        X x3 = X(x0); 
    }

    编译器对于以下代码有两个转化:
    1. 重写每个定义, 剥除初始化操作.
    2. class 的 copy constructor 的调用操作会安插进去.
    可能的代码如下:

    void FooBar()
    {
        //剥离初始化操作
        X x1;
            X x2; 
            X x3;
    
        //安插 copy constructor 的代码
        x1.X::X(x0);
        x2.X::X(x0);
        x3.X::X(x0);
    }

    其中如 x1.X::X(x0) 就是对 X::X(const X&) 的调用.

    三丶参数的初始化
    考察以下代码:

    void Foo(X x){/* ... */}
    X xx;
    Foo(xx);

    将会要求局部实体(local instance) x0 以深拷贝的方式将 xx 作为初值. 这个策略是使用一个暂时性的 object, 调用 copy constructor 初始化后把它传入函数. 因此实际上可能的代码为:

    //暂时对象
    X __temp0;
    
    //调用 copy constructor
    __temp0.X::X(xx);
    void Foo(__temp0);

    如此存在一个问题, __temp0 是以 bitwise 的方式拷贝到 Foo() 的作用域中的, 但若是这样, Foo(X x) 便要变成 Foo(X &x), 因此, 至此编译器只是做了一半工作, 接下来的动作可能在接下来的章节有所描述.

    四丶返回值初始化
    考察以下代码:

    X Bar()
    {
        X xx;
        //...
        return xx;
    }


    怎样把 Bar() 的返回值从 xx 这个局部变量中拷出来?
    考察以下代码:

    //可能的代码
    void Bar(X &__result)                 //额外的参数
    {
        X xx;                             //剥离
        xx.X::X()                       //default constructor
        //...
        __result.X::X(xx);               //编译器产生的 copy constructor 操作
        return;
    }
    
    所以对于 Bar():
    //你看到的
    X xx = Bar();
    
    //可能实际的代码
    X xx;
    Bar(xx);
    
    //你看到的
    Bar().MemberFunc()                   //MemberFunc() 为 class X 的 member function
    
    //可能实际上的代码
    X __temp0;                          //编译器会产生一个临时 object
    (Bar(__temp0), __temp0).MemberFunc();
    
    //你看到的
    X (*pf)();
    pf = Bar;                          //pf 为 函数指针
    
    //可能实际的代码
    X (*pf)(X&)                        //实际此函数指针与该函数的真面目相同
    pf = Bar;    
  • 相关阅读:
    Codeforces 547D. Mike and Fish 题解
    Codeforces 521E. Cycling City 题解
    Codeforces 585E. Present for Vitalik the Philatelist 题解
    Codeforces 605E. Intergalaxy Trips 题解
    AGC033D
    第3次作业:卷积神经网络
    Linux下如何编写go语言程序实现菲波拉契数列
    C语言常见典型错误汇总(助教)
    第一次作业:深度学习基础
    数论复习_欧几里得算法与扩展欧几里得算法
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4100223.html
Copyright © 2011-2022 走看看