免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lipingtababa
打印 上一主题 下一主题

[C++] 你们的代码会用引用吗? [复制链接]

论坛徽章:
0
121 [报告]
发表于 2008-11-25 09:31 |只看该作者
我知道是正确的语义行为.
但这种行为应该在程序中尽量避免的行为. 因为他破坏了程序摸块(FUNC)的封闭性. 如果实在要用,也必须显式地给出最好.


原帖由 sbc19861004 于 2008-11-25 08:57 发表

引用本身就表明拿到的是调用它的函数中的变量,而不是该变量的拷贝,在函数里修改了变量的值,这是正确的语义行为呀。
就像你写一个交换函数,本意就是要交换两个变量的值,也就是修改了调用它的函数中的变量。

论坛徽章:
0
122 [报告]
发表于 2008-11-25 09:56 |只看该作者
原帖由 sbc19861004 于 2008-11-25 08:57 发表

引用本身就表明拿到的是调用它的函数中的变量,而不是该变量的拷贝,在函数里修改了变量的值,这是正确的语义行为呀。
就像你写一个交换函数,本意就是要交换两个变量的值,也就是修改了调用它的函数中的变量。



/* 甲设计了fun函数 */
void fun(int &n)
{
        n++;
        printf("in fun. n=%d\n",n);
}

int main()
{
        int n=88;
        fun(n);  /* 你使用fun函数 */
        printf("n=%d\n",n);
        return 0;
}

你要使用甲设计的fun函数,需要知道函数参数的用法。过些日子后(不用时间长,一周即可),你再看“fun(n);”时,你肯定会想n是传数值还是传引用?
但是,如果fun的参数是指针类型,那么你看到“fun(&n);”时不就一目了然了,你就不用想那么多了。

论坛徽章:
0
123 [报告]
发表于 2008-11-25 10:33 |只看该作者
问题是, 程序中带副作用的函数应该尽量少. 越少越好.
你可以比较:
1)仅仅用C的参数传递, 和非常少的指针参数的函数组成的一个程序
2)全部用引用的函数.

论坛徽章:
0
124 [报告]
发表于 2008-11-25 10:46 |只看该作者
原帖由 sbc19861004 于 2008-11-24 19:27 发表

你这个说法很有新意,能不能具体解释一下什么是“社会分工协作”,引用怎么违犯了?在这点上c,是不是使用指针就不会违反?
讨论而已,希望本着事实为例的原则,不要恶语相攻。


我简单地说两句,欢迎讨论。
在自然界中,任何物体都有地址。在C语言中,知道了*代表地址,就很容易联想到:**代表地址的地址,***代表地址的地址的地址,...这是多么自然的事情。但是!C++的引用能让你联想到什么?你什么也联想不到!因为C++的引用根本就是没有内容的东西!思维是物质运动的结果,没有物质也就没有思维,所以不会从没有内容的东西想到什么。

论坛徽章:
0
125 [报告]
发表于 2008-11-25 11:01 |只看该作者
原帖由 思一克 于 2008-11-24 18:33 发表
问题是, 程序中带副作用的函数应该尽量少. 越少越好.
你可以比较:
1)仅仅用C的参数传递, 和非常少的指针参数的函数组成的一个程序
2)全部用引用的函数.


深表赞同。:wink:

论坛徽章:
0
126 [报告]
发表于 2008-11-25 13:11 |只看该作者

引用就是用指针实现的

fun函数用引用,fun1函数用指针,两个函数功能一样。反汇编后,两个函数的汇编代码完全一样。


fun函数:

void fun(int &n)
{
        n++;
        printf("in fun. n=%d\n",n);
}

fun函数的汇编代码:

4:    void fun(int &n)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
6:        n++;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   mov         ecx,dword ptr [eax]
0040103D   add         ecx,1
00401040   mov         edx,dword ptr [ebp+8]
00401043   mov         dword ptr [edx],ecx
7:        printf("in fun. n=%d\n",n);
00401045   mov         eax,dword ptr [ebp+8]
00401048   mov         ecx,dword ptr [eax]
0040104A   push        ecx
0040104B   push        offset string "in fun. n=%d\n" (0042201c)
00401050   call        printf (004010e0)
00401055   add         esp,8
8:    }



fun1函数:

void fun1(int *p)
{
        (*p)++;
        printf("in fun1. *p=%d\n",*p);
}


fun1函数的汇编代码:

9:
10:   void fun1(int *p)
11:   {
00401070   push        ebp
00401071   mov         ebp,esp
00401073   sub         esp,40h
00401076   push        ebx
00401077   push        esi
00401078   push        edi
00401079   lea         edi,[ebp-40h]
0040107C   mov         ecx,10h
00401081   mov         eax,0CCCCCCCCh
00401086   rep stos    dword ptr [edi]
12:       (*p)++;
00401088   mov         eax,dword ptr [ebp+8]
0040108B   mov         ecx,dword ptr [eax]
0040108D   add         ecx,1
00401090   mov         edx,dword ptr [ebp+8]
00401093   mov         dword ptr [edx],ecx
13:       printf("in fun1. *p=%d\n",*p);
00401095   mov         eax,dword ptr [ebp+8]
00401098   mov         ecx,dword ptr [eax]
0040109A   push        ecx
0040109B   push        offset string "in fun1. *p=%d\n" (00422fb4)
004010A0   call        printf (004010e0)
004010A5   add         esp,8
14:   }

论坛徽章:
0
127 [报告]
发表于 2008-11-25 13:17 |只看该作者
我早在一个批评引用的贴中说过了.

本质上就是指针.

原帖由 cbvxvx 于 2008-11-25 13:11 发表
fun函数用引用,fun1函数用指针,两个函数功能一样。反汇编后,两个函数的汇编代码完全一样。


fun函数:

void fun(int &n)
{
        n++;
        printf("in fun. n=%d\n",n);
}

fun函数的汇编代码:

4:  ...

论坛徽章:
0
128 [报告]
发表于 2008-11-25 13:22 |只看该作者
原帖由 思一克 于 2008-11-25 13:17 发表
我早在一个批评引用的贴中说过了.

本质上就是指针.



嗯,向思版主学习。

论坛徽章:
0
129 [报告]
发表于 2008-11-27 09:37 |只看该作者
原帖由 cbvxvx 于 2008-11-25 09:56 发表



/* 甲设计了fun函数 */
void fun(int &n)
{
        n++;
        printf("in fun. n=%d\n",n);
}

int main()
{
        int n=88;
        fun(n);  /* 你使用fun函数 */
        printf("n=%d\n",n);
        return 0;
}

你要使 ...


你这是从c语言的值传递的观点衍生出来的。
引用也可以很好的满足数据隔离。
可能修改的数据使用值传递,即:void func(int &)
不修改的数据使用const严格声明,即:void funct(const int &)
也可以达到数据隔离的效果
引用的基本观点即是数据是在程序中只拥有一份拷贝

论坛徽章:
0
130 [报告]
发表于 2008-11-27 09:57 |只看该作者
原帖由 newcuuser 于 2008-11-25 10:46 发表


我简单地说两句,欢迎讨论。
在自然界中,任何物体都有地址。在C语言中,知道了*代表地址,就很容易联想到:**代表地址的地址,***代表地址的地址的地址,...这是多么自然的事情。但是!C++的引用能让你联 ...


那你有没有联想到这种情况,一个地址代表长10米的墙,你强制转换成一只长1米的羊,你对这个地址++,现在这个地址是什么,它有什么意义。
引用的基本观点,结构是原子的,对结构的转换只是更换结构对外的表现形式,而不会在改变结构的内部表示的大小和行为
如:
class a{
....
};

class b : public a {
....
};

b testb;
a testa = &b;

使用 引用,规定了对象转换行为,而指针只是以内存的大小来代表一个对象,转换只是更换了从该指针指向的首地址向上或向下数的内存大小。
(当然 c++中为了避免这种行为,对于具有继承关系的指针转换没有再使用这个指针的语义,而是传递了对应的地址,如:
b *testb = new b();
a *testa = testb;

这是testa并不指向指针testb的地址,而是获得testb指向的对象中的a的对象的地址,这个语义是引用的)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP