ostream

    几乎所有关于c++的书籍都会提到<<操作支持很多数据类型。这些支持是在ostream中完成的。通过反汇编之后的代码,可以看到ostream中的<<操作被调用:

    1. _main PROC
    2. push OFFSET $SG37112
    3. push OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
    4. call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
    5. $char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    6. add esp, 8
    7. xor eax, eax
    8. ret 0
    9. _main ENDP

    对示例程序做如下修改:

    1. $SG37112 DB world!’, 0aH, 00H
    2. $SG37113 DB Hello, ’, 00H
    3. _main PROC
    4. call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
    5. $char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    6. add esp, 8
    7. push OFFSET $SG37112 ; world!’
    8. push eax ; result of previous function
    9. call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?
    10. $char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    11. add esp, 8
    12. xor eax, eax
    13. ret 0
    14. _main ENDP

    如果用函数f()替换<<运算符,示例代码等价于:

    f(f(std::cout, "Hello, "), "world!")

    引用: 在c++中,引用和指针一样,但是使用的时候更安全,因为在使用引用的时候几乎不会发生错误。例如,引用必须始终指向一个相应类型的对象,而不能为NULL。甚至于,引用不能被改变,不能将一个对象的引用重新赋值以指向另一个对象。 如果我们尝试修改指针的例子(9),将指针替换为引用:

    可以想到,编译后的代码和使用指针生成的代码一致。

    1. _x$ = 8 ; size = 4
    2. _sum$ = 16 ; size = 4
    3. _product$ = 20 ; size = 4
    4. ?f2@@YAXHHAAH0@Z PROC ; f2
    5. mov ecx, DWORD PTR _y$[esp-4]
    6. mov eax, DWORD PTR _x$[esp-4]
    7. lea edx, DWORD PTR [eax+ecx]
    8. imul eax, ecx
    9. mov ecx, DWORD PTR _product$[esp-4]
    10. push esi
    11. mov esi, DWORD PTR _sum$[esp]
    12. mov DWORD PTR [esi], edx
    13. mov DWORD PTR [ecx], eax
    14. pop esi
    15. ?f2@@YAXHHAAH0@Z ENDP ; f2