程序的转化 & 明确的初始化操作 & 参数的初始化 & 返回值的初始化

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

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;    
时间: 2024-10-22 12:59:32

程序的转化 & 明确的初始化操作 & 参数的初始化 & 返回值的初始化的相关文章

引用参数与引用返回值 类的拷贝构造

引用地址  http://www.cnblogs.com/bigshow/archive/2008/11/10/1330514.html 经常看到这样的声明:T& func(T& t),这种声明和T func(T t)有什么区别?书上的解释是为了提高效率,究竟是如何提高效率的呢?内部执行了什么操作?本文通过8个小例子对引用参数和引用返回进行了一次彻底的排查.    首先看一下在类的成员函数中的引用参数和引用返回值: 类定义class A{     public:      int x; A

工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码如下: # TestGroovy.groovy 定义testC方法,传入3个参数,返回处理后的数据 def testC(int numA, int numB, int numC) { "传入参数:" + numA + numB + numC + "计算之和为:" + (

Golang中interface{}作为函数参数和函数返回值的使用

package main import (     "errors"     "fmt" ) type item struct {     Name string } func (i item) String() string {     return fmt.Sprintf("item name: %v", i.Name) } type person struct {     Name string     Sex  string } func

httpclient4.x调用cxf发布的webservice的某个方法(有参数,有返回值)(未整合spring)

原文:httpclient4.x调用cxf发布的webservice的某个方法(有参数,有返回值)(未整合spring) 源代码下载地址:httpclient4.x调用cxf发布的webservice的某个方法(有参数,有返回值)(未整合spring) 采用spring + cxf编写服务端 httpclient4编写客户端调用 如题,代码没有jar 完整包: 链接:http://pan.baidu.com/share/link?shareid=2162612373&uk=402880896 密

PHP_零基础学php_3PHP函数、传参函数、默认参数、函数返回值

<?php function say_hello() //无参数 { $name="tang"; echo "hello,".$name; echo "<br />"; echo "<hr />"; } say_hello();//函数调用 function say_helloS($some_name)//有参数 { echo "hello,".$some_name; echo

C# 调用存储过程操作 OUTPUT参数和Return返回值

本文转载:http://www.cnblogs.com/libingql/archive/2010/05/02/1726104.html 存储过程是存放在数据库服务器上的预先编译好的sql语句.使用存储过程,可以直接在数据库中存储并运行功能强大的任务.存储过程在第一应用程序执行时进行语法检查和编译,编译好的版本保存在高速缓存中.在执行重复任务时,存储过程可以提高性能和一致性.由于存储过程可以将一系列对数据库的操作放在数据库服务器上执行,因而可以降低Web服务器的负载,提高整个系统的性能. 1.创

对象做函数参数和函数返回值时,调用复制构造函数,构造函数,析构函数的情况

// 对象做函数参数和返回值.cpp : 定义控制台应用程序的入口点.//exit(0)表示正常退出程序,exit(0)表示异常退出 //在调用input时,编译器用对象A去创建了形参对象temp,调用了复制构造函数,对象A中的数据复制给了对象temp// 在input函数中,执行temp.set(s),为对象temp中数据成员str申请了动态储存空间,并设置了输入的字符串//并没有改变实参A中的数据成员str的储存空间,故在执行语句A.show()后输出的字符串并没有改变.在函数调用结束后 /

const参数,const返回值与const函数

在C++程序中,经常用const 来限制对一个对象的操作,例如,将一个变量定义为const 的: const  int  n=3; 则这个变量的值不能被修改,即不能对变量赋值. const 这个关键字经常出现在函数的定义中,而且会出现在不同的位置,比如: int  strcmp (const   char  *str1,const    char  *str2); const    int  & min (int  &, int  &); void  printMessage (c

引用参数,引用返回值

函数形参诗引用,程序输出如程序最后的注释,表明引用s代表的是对象s2. //函数中的引用 #include<iostream> using namespace std; class Sample { int x; public: Sample(int a): x(a) { cout<<"call constructor Sample(int a)"<<endl; } Sample(Sample &a): x(a.x) { cout <&