Const 重载解析

书上和网上在很多地方都对const 的重载做了一些解释,但感觉都不是很详细。还有很多同学在不同的地方发问关于const 重载的问题,这里我又重新看了一下,做了一个简单的分析也可能有不对的地方,欢迎讨论。
所谓重载,是指允许存在多个同名函数,而这些函数的参数表不同,即函数名相同但函数的签名不同。重载并不是面向对象编程的特有属性,这是因为重载是在编译阶段实现的,编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(这一点稍后有例子)。了

 

 Const 参数重载解析:

 

关于const 重载几乎在所有c++的书中者提到过但大部分只是一句话,例如在《C++ primer》一书中这样描述:“可基于函数的引用形参是指向 const 对象还是指向非 const 对象,实现函数重载。将引用形参定义为 const 来重载函数是合法的,因为编译器可以根据实参是否为 const 确定调用哪一个函数。”
但是这一段描述并没有给出引用、指针和值传递前加const的实质区别是什么。在用非const的指针,引用和值均可转化为const的。这一点没有太多可说明的东东。

对于函数值传递的情况,因为参数传递是通过复制实参创建一个临时变量传递进函数的,函数内只能改变临时变量,但无法改变实参。则这个时候无论加不加const对实参不会产生任何影响。但是在引用或指针传递函数调用中,因为传进去的是一个引用或指针,这样函数内部可以改变引用或指针所指向的变量,这时const 才是实实在在地保护了实参所指向的变量。因为在编译阶段编译器对调用函数的选择是根据实参进行的,所以,只有引用传递和指针传递可以用是否加const来重载。
下面给出一个例子可能就更明白了:

 

C++ 代码
1 #include<iostream>
2
3  class A{
4  public:
5 A();
6 int foo(int *test);
7 int foo(const int *test);
8 };
9 A::A(){
10 }
11  int A::foo(int *test){
12 std::cout << *test << " A::foo(int *test)" <<std::endl;
13 return 1;
14 }
15  int A::foo(const int *test){
16 std::cout << *test << " A::foo(const int *test)" <<std::endl;
17 return 1;
18 }
19  int main()
20 {
21 const int b =5;
22 int c = 3;
23 A a;
24 a.foo(&b);
25 a.foo(&c);
26 return 1;
27 }
28  

 

 

输出:

 

5 A::foo(const int *test)
3 A::foo(int *test)

 

 

那么编译器又是怎样工作的,通过g++ -S选项将汇编代码生成出来,通过AT&T汇编代码可以看出一些端倪来(之所以用AT&T汇编是因为VS生成的中间代码实在是让人头晕):

 

代码
1 .file "overload.cpp"
2 .section .ctors,"aw",@progbits
3 .align 4
4 .long _GLOBAL__I__ZN1AC2Ev
5 .text
6 .align 2
7 .globl _ZN1AC2Ev
8 .type _ZN1AC2Ev, @function
9  _ZN1AC2Ev:
10 .LFB1399:
11 pushl %ebp
12 .LCFI0:
13 movl %esp, %ebp
14 .LCFI1:
15 popl %ebp
16 ret
17 .LFE1399:
18 .size _ZN1AC2Ev, .-_ZN1AC2Ev
19 .globl __gxx_personality_v0
20 .align 2
21 .globl _ZN1AC1Ev
22 .type _ZN1AC1Ev, @function
23  _ZN1AC1Ev:
24 .LFB1400:
25 pushl %ebp
26 .LCFI2:
27 movl %esp, %ebp
28 .LCFI3:
29 popl %ebp
30 ret
31 .LFE1400:
32 .size _ZN1AC1Ev, .-_ZN1AC1Ev
33 .align 2
34 .type _Z41__static_initialization_and_destruction_0ii, @function
35  _Z41__static_initialization_and_destruction_0ii:
36 .LFB1411:
37 pushl %ebp
38 .LCFI4:
39 movl %esp, %ebp
40 .LCFI5:
41 subl $24, %esp
42 .LCFI6:
43 movl %eax, -4(%ebp)
44 movl %edx, -8(%ebp)
45 cmpl $1, -4(%ebp)
46 jne .L9
47 cmpl $65535, -8(%ebp)
48 jne .L9
49 movl $_ZSt8__ioinit, (%esp)
50 call _ZNSt8ios_base4InitC1Ev
51 movl $__dso_handle, 8(%esp)
52 movl $0, 4(%esp)
53 movl $__tcf_0, (%esp)
54 call __cxa_atexit
55 .L9:
56 leave
57 ret
58 .LFE1411:
59 .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
60 .align 2
61 .type _GLOBAL__I__ZN1AC2Ev, @function
62  _GLOBAL__I__ZN1AC2Ev:
63 .LFB1413:
64 pushl %ebp
65 .LCFI7:
66 movl %esp, %ebp
67 .LCFI8:
68 subl $8, %esp
69 .LCFI9:
70 movl $65535, %edx
71 movl $1, %eax
72 call _Z41__static_initialization_and_destruction_0ii
73 leave
74 ret
75 .LFE1413:
76 .size _GLOBAL__I__ZN1AC2Ev, .-_GLOBAL__I__ZN1AC2Ev
77 .align 2
78 .type __tcf_0, @function
79  __tcf_0:
80 .LFB1412:
81 pushl %ebp
82 .LCFI10:
83 movl %esp, %ebp
84 .LCFI11:
85 subl $8, %esp
86 .LCFI12:
87 movl $_ZSt8__ioinit, (%esp)
88 call _ZNSt8ios_base4InitD1Ev
89 leave
90 ret
91 .LFE1412:
92 .size __tcf_0, .-__tcf_0
93 .section .rodata
94 .LC0:
95 .string " A::foo(const int *test)"
96 .text
97 .align 2
98 .globl _ZN1A3fooEPKi
99 .type _ZN1A3fooEPKi, @function
100  _ZN1A3fooEPKi:
101 .LFB1402:
102 pushl %ebp
103 .LCFI13:
104 movl %esp, %ebp
105 .LCFI14:
106 subl $8, %esp
107 .LCFI15:
108 movl 12(%ebp), %eax
109 movl (%eax), %eax
110 movl %eax, 4(%esp)
111 movl $_ZSt4cout, (%esp)
112 call _ZNSolsEi
113 movl $.LC0, 4(%esp)
114 movl %eax, (%esp)
115 call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
116 movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
117 movl %eax, (%esp)
118 call _ZNSolsEPFRSoS_E
119 movl $1, %eax
120 leave
121 ret
122 .LFE1402:
123 .size _ZN1A3fooEPKi, .-_ZN1A3fooEPKi
124 .section .rodata
125 .LC1:
126 .string " A::foo(int *test)"
127 .text
128 .align 2
129 .globl _ZN1A3fooEPi
130 .type _ZN1A3fooEPi, @function
131  _ZN1A3fooEPi:
132 .LFB1401:
133 pushl %ebp
134 .LCFI16:
135 movl %esp, %ebp
136 .LCFI17:
137 subl $8, %esp
138 .LCFI18:
139 movl 12(%ebp), %eax
140 movl (%eax), %eax
141 movl %eax, 4(%esp)
142 movl $_ZSt4cout, (%esp)
143 call _ZNSolsEi
144 movl $.LC1, 4(%esp)
145 movl %eax, (%esp)
146 call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
147 movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
148 movl %eax, (%esp)
149 call _ZNSolsEPFRSoS_E
150 movl $1, %eax
151 leave
152 ret
153 .LFE1401:
154 .size _ZN1A3fooEPi, .-_ZN1A3fooEPi
155 .align 2
156 .globl main
157 .type main, @function
158  main:
159 .LFB1403:
160 leal 4(%esp), %ecx
161 .LCFI19:
162 andl $-16, %esp
163 pushl -4(%ecx)
164 .LCFI20:
165 pushl %ebp
166 .LCFI21:
167 movl %esp, %ebp
168 .LCFI22:
169 pushl %ecx
170 .LCFI23:
171 subl $36, %esp
172 .LCFI24:
173 movl $5, -8(%ebp)
174 movl $3, -12(%ebp)
175 leal -13(%ebp), %eax
176 movl %eax, (%esp)
177 call _ZN1AC1Ev
178 leal -8(%ebp), %eax
179 movl %eax, 4(%esp)
180 leal -13(%ebp), %eax
181 movl %eax, (%esp)
182 call _ZN1A3fooEPKi
183 leal -12(%ebp), %eax
184 movl %eax, 4(%esp)
185 leal -13(%ebp), %eax
186 movl %eax, (%esp)
187 call _ZN1A3fooEPi
188 movl $1, %eax
189 addl $36, %esp
190 popl %ecx
191 popl %ebp
192 leal -4(%ecx), %esp
193 ret
194 .LFE1403:
195 .size main, .-main
196 .local _ZSt8__ioinit
197 .comm _ZSt8__ioinit,1,1
198 .weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once
199 .weakref _Z27__gthrw_pthread_getspecificj,pthread_getspecific
200 .weakref _Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
201 .weakref _Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
202 .weakref _Z22__gthrw_pthread_cancelm,pthread_cancel
203 .weakref _Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
204 .weakref _Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
205 .weakref _Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
206 .weakref _Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
207 .weakref _Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
208 .weakref _Z26__gthrw_pthread_key_deletej,pthread_key_delete
209 .weakref _Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
210 .weakref _Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
211 .weakref _Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
212 .section .eh_frame,"a",@progbits
213 .Lframe1:
214 .long .LECIE1-.LSCIE1
215 .LSCIE1:
216 .long 0x0
217 .byte 0x1
218 .string "zP"
219 .uleb128 0x1
220 .sleb128 -4
221 .byte 0x8
222 .uleb128 0x5
223 .byte 0x0
224 .long __gxx_personality_v0
225 .byte 0xc
226 .uleb128 0x4
227 .uleb128 0x4
228 .byte 0x88
229 .uleb128 0x1
230 .align 4
231 .LECIE1:
232 .LSFDE5:
233 .long .LEFDE5-.LASFDE5
234 .LASFDE5:
235 .long .LASFDE5-.Lframe1
236 .long .LFB1411
237 .long .LFE1411-.LFB1411
238 .uleb128 0x0
239 .byte 0x4
240 .long .LCFI4-.LFB1411
241 .byte 0xe
242 .uleb128 0x8
243 .byte 0x85
244 .uleb128 0x2
245 .byte 0x4
246 .long .LCFI5-.LCFI4
247 .byte 0xd
248 .uleb128 0x5
249 .align 4
250 .LEFDE5:
251 .LSFDE7:
252 .long .LEFDE7-.LASFDE7
253 .LASFDE7:
254 .long .LASFDE7-.Lframe1
255 .long .LFB1413
256 .long .LFE1413-.LFB1413
257 .uleb128 0x0
258 .byte 0x4
259 .long .LCFI7-.LFB1413
260 .byte 0xe
261 .uleb128 0x8
262 .byte 0x85
263 .uleb128 0x2
264 .byte 0x4
265 .long .LCFI8-.LCFI7
266 .byte 0xd
267 .uleb128 0x5
268 .align 4
269 .LEFDE7:
270 .LSFDE9:
271 .long .LEFDE9-.LASFDE9
272 .LASFDE9:
273 .long .LASFDE9-.Lframe1
274 .long .LFB1412
275 .long .LFE1412-.LFB1412
276 .uleb128 0x0
277 .byte 0x4
278 .long .LCFI10-.LFB1412
279 .byte 0xe
280 .uleb128 0x8
281 .byte 0x85
282 .uleb128 0x2
283 .byte 0x4
284 .long .LCFI11-.LCFI10
285 .byte 0xd
286 .uleb128 0x5
287 .align 4
288 .LEFDE9:
289 .LSFDE11:
290 .long .LEFDE11-.LASFDE11
291 .LASFDE11:
292 .long .LASFDE11-.Lframe1
293 .long .LFB1402
294 .long .LFE1402-.LFB1402
295 .uleb128 0x0
296 .byte 0x4
297 .long .LCFI13-.LFB1402
298 .byte 0xe
299 .uleb128 0x8
300 .byte 0x85
301 .uleb128 0x2
302 .byte 0x4
303 .long .LCFI14-.LCFI13
304 .byte 0xd
305 .uleb128 0x5
306 .align 4
307 .LEFDE11:
308 .LSFDE13:
309 .long .LEFDE13-.LASFDE13
310 .LASFDE13:
311 .long .LASFDE13-.Lframe1
312 .long .LFB1401
313 .long .LFE1401-.LFB1401
314 .uleb128 0x0
315 .byte 0x4
316 .long .LCFI16-.LFB1401
317 .byte 0xe
318 .uleb128 0x8
319 .byte 0x85
320 .uleb128 0x2
321 .byte 0x4
322 .long .LCFI17-.LCFI16
323 .byte 0xd
324 .uleb128 0x5
325 .align 4
326 .LEFDE13:
327 .LSFDE15:
328 .long .LEFDE15-.LASFDE15
329 .LASFDE15:
330 .long .LASFDE15-.Lframe1
331 .long .LFB1403
332 .long .LFE1403-.LFB1403
333 .uleb128 0x0
334 .byte 0x4
335 .long .LCFI19-.LFB1403
336 .byte 0xc
337 .uleb128 0x1
338 .uleb128 0x0
339 .byte 0x9
340 .uleb128 0x4
341 .uleb128 0x1
342 .byte 0x4
343 .long .LCFI20-.LCFI19
344 .byte 0xc
345 .uleb128 0x4
346 .uleb128 0x4
347 .byte 0x4
348 .long .LCFI21-.LCFI20
349 .byte 0xe
350 .uleb128 0x8
351 .byte 0x85
352 .uleb128 0x2
353 .byte 0x4
354 .long .LCFI22-.LCFI21
355 .byte 0xd
356 .uleb128 0x5
357 .byte 0x4
358 .long .LCFI23-.LCFI22
359 .byte 0x84
360 .uleb128 0x3
361 .align 4
362 .LEFDE15:
363 .ident "GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)"
364 .section .note.GNU-stack,"",@progbits

如上面的代码函数:

 

int foo(int *test);和int foo(const int *test);分别被编译器生成名为:_ZN1A3fooEPKi和_ZN1A3fooEPi(这两个名字会因为编译器的不同而不同,名字只是一个区分的符号而已不用深究,只用知道重载的函数经过编译器的处理函数名字已经发生了变化。所以对于后面的汇编和链接工作就不存在重载的问题了。)这里也同时说明对重载来说在编译阶段已经完成。

对于a.foo(&b);因为变量b有const修饰所以就调用了int foo(const int *test);对于a.foo(&c);调用int foo(int *test);因为这个是精确匹配的。但是如果没有定义int foo(const int *test);则在代码24行会出现编译错误。反过来如果没有定义函数:int foo(int *test);如下:

 

代码
1 #include<iostream>
2
3  class A{
4  public:
5 A();
6  // int foo(int *test);
7   int foo(const int *test);
8 };
9 A::A(){
10 }
11  /*int A::foo(int *test){
12 std::cout << *test << " A::foo(int *test)" <<std::endl;
13 return 1;
14 }
15 */
16 int A::foo(const int *test){
17 std::cout << *test << " A::foo(const int *test)" <<std::endl;
18 return 1;
19 }
20 int main()
21 {
22 const int b =5;
23 int c = 3;
24 A a;
25 a.foo(&b);
26 a.foo(&c);
27 return 1;
28 }

则输出结果为:

 

 

1 5 A::foo(const int *test)
2 3 A::foo(const int *test)

 

原因c++ primer上讲的很清楚:“We can use a nonconst object to initializer either a const or nonconst reference. However, initializing a const reference to a nonconst object requires a conversion, whereas initializing a nonconst parameter is an exact match.”

 

 

const 成员函数重载的解析:

 

const 成员函数重载的解析和const参数重载解析的原理可以说是一样的。之所以这样说是因为const成员函数的解析可被看做是对函数this参数用const来修饰的过程。例如下面代码:

 

代码
1 #include<iostream>
2
3 class A{
4 public:
5 A();
6 int foo(int *test); //可看做:int foo(A *this,int *test);
7 int foo(int *test) const;//可看做:int foo(const A *this,int *test);
8 };
9 A::A(){
10 }
11 int A::foo(int *test){
12 std::cout << *test << "foo" <<std::endl;
13 return 1;
14 }
15 int A::foo(int *test) const {
16 std::cout << *test << "foo const" <<std::endl;
17 return 1;
18 }
19 int main()
20 {
21 int b = 5;
22 const A a;
23 a.foo(&b);
24 return 1;
25 }
26

生成汇编为:

代码
1 .file "overload1.cpp"
2 .section .ctors,"aw",@progbits
3 .align 4
4 .long _GLOBAL__I__ZN1AC2Ev
5 .text
6 .align 2
7 .globl _ZN1AC2Ev
8 .type _ZN1AC2Ev, @function
9 _ZN1AC2Ev:
10 .LFB1399:
11 pushl %ebp
12 .LCFI0:
13 movl %esp, %ebp
14 .LCFI1:
15 popl %ebp
16 ret
17 .LFE1399:
18 .size _ZN1AC2Ev, .-_ZN1AC2Ev
19 .globl __gxx_personality_v0
20 .align 2
21 .globl _ZN1AC1Ev
22 .type _ZN1AC1Ev, @function
23 _ZN1AC1Ev:
24 .LFB1400:
25 pushl %ebp
26 .LCFI2:
27 movl %esp, %ebp
28 .LCFI3:
29 popl %ebp
30 ret
31 .LFE1400:
32 .size _ZN1AC1Ev, .-_ZN1AC1Ev
33 .align 2
34 .type _Z41__static_initialization_and_destruction_0ii, @function
35 _Z41__static_initialization_and_destruction_0ii:
36 .LFB1411:
37 pushl %ebp
38 .LCFI4:
39 movl %esp, %ebp
40 .LCFI5:
41 subl $24, %esp
42 .LCFI6:
43 movl %eax, -4(%ebp)
44 movl %edx, -8(%ebp)
45 cmpl $1, -4(%ebp)
46 jne .L9
47 cmpl $65535, -8(%ebp)
48 jne .L9
49 movl $_ZSt8__ioinit, (%esp)
50 call _ZNSt8ios_base4InitC1Ev
51 movl $__dso_handle, 8(%esp)
52 movl $0, 4(%esp)
53 movl $__tcf_0, (%esp)
54 call __cxa_atexit
55 .L9:
56 leave
57 ret
58 .LFE1411:
59 .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
60 .align 2
61 .type _GLOBAL__I__ZN1AC2Ev, @function
62 _GLOBAL__I__ZN1AC2Ev:
63 .LFB1413:
64 pushl %ebp
65 .LCFI7:
66 movl %esp, %ebp
67 .LCFI8:
68 subl $8, %esp
69 .LCFI9:
70 movl $65535, %edx
71 movl $1, %eax
72 call _Z41__static_initialization_and_destruction_0ii
73 leave
74 ret
75 .LFE1413:
76 .size _GLOBAL__I__ZN1AC2Ev, .-_GLOBAL__I__ZN1AC2Ev
77 .align 2
78 .type __tcf_0, @function
79 __tcf_0:
80 .LFB1412:
81 pushl %ebp
82 .LCFI10:
83 movl %esp, %ebp
84 .LCFI11:
85 subl $8, %esp
86 .LCFI12:
87 movl $_ZSt8__ioinit, (%esp)
88 call _ZNSt8ios_base4InitD1Ev
89 leave
90 ret
91 .LFE1412:
92 .size __tcf_0, .-__tcf_0
93 .section .rodata
94 .LC0:
95 .string "foo const"
96 .text
97 .align 2
98 .globl _ZNK1A3fooEPi
99 .type _ZNK1A3fooEPi, @function
100 _ZNK1A3fooEPi:
101 .LFB1402:
102 pushl %ebp
103 .LCFI13:
104 movl %esp, %ebp
105 .LCFI14:
106 subl $8, %esp
107 .LCFI15:
108 movl 12(%ebp), %eax
109 movl (%eax), %eax
110 movl %eax, 4(%esp)
111 movl $_ZSt4cout, (%esp)
112 call _ZNSolsEi
113 movl $.LC0, 4(%esp)
114 movl %eax, (%esp)
115 call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
116 movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
117 movl %eax, (%esp)
118 call _ZNSolsEPFRSoS_E
119 movl $1, %eax
120 leave
121 ret
122 .LFE1402:
123 .size _ZNK1A3fooEPi, .-_ZNK1A3fooEPi
124 .align 2
125 .globl main
126 .type main, @function
127 main:
128 .LFB1403:
129 leal 4(%esp), %ecx
130 .LCFI16:
131 andl $-16, %esp
132 pushl -4(%ecx)
133 .LCFI17:
134 pushl %ebp
135 .LCFI18:
136 movl %esp, %ebp
137 .LCFI19:
138 pushl %ecx
139 .LCFI20:
140 subl $36, %esp
141 .LCFI21:
142 movl $5, -8(%ebp)
143 leal -9(%ebp), %eax
144 movl %eax, (%esp)
145 call _ZN1AC1Ev
146 leal -8(%ebp), %eax
147 movl %eax, 4(%esp)
148 leal -9(%ebp), %eax
149 movl %eax, (%esp)
150 call _ZNK1A3fooEPi
151 movl $1, %eax
152 addl $36, %esp
153 popl %ecx
154 popl %ebp
155 leal -4(%ecx), %esp
156 ret
157 .LFE1403:
158 .size main, .-main
159 .section .rodata
160 .LC1:
161 .string "foo"
162 .text
163 .align 2
164 .globl _ZN1A3fooEPi
165 .type _ZN1A3fooEPi, @function
166 _ZN1A3fooEPi:
167 .LFB1401:
168 pushl %ebp
169 .LCFI22:
170 movl %esp, %ebp
171 .LCFI23:
172 subl $8, %esp
173 .LCFI24:
174 movl 12(%ebp), %eax
175 movl (%eax), %eax
176 movl %eax, 4(%esp)
177 movl $_ZSt4cout, (%esp)
178 call _ZNSolsEi
179 movl $.LC1, 4(%esp)
180 movl %eax, (%esp)
181 call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
182 movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
183 movl %eax, (%esp)
184 call _ZNSolsEPFRSoS_E
185 movl $1, %eax
186 leave
187 ret
188 .LFE1401:
189 .size _ZN1A3fooEPi, .-_ZN1A3fooEPi
190 .local _ZSt8__ioinit
191 .comm _ZSt8__ioinit,1,1
192 .weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once
193 .weakref _Z27__gthrw_pthread_getspecificj,pthread_getspecific
194 .weakref _Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
195 .weakref _Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
196 .weakref _Z22__gthrw_pthread_cancelm,pthread_cancel
197 .weakref _Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
198 .weakref _Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
199 .weakref _Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
200 .weakref _Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
201 .weakref _Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
202 .weakref _Z26__gthrw_pthread_key_deletej,pthread_key_delete
203 .weakref _Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
204 .weakref _Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
205 .weakref _Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
206 .section .eh_frame,"a",@progbits
207 .Lframe1:
208 .long .LECIE1-.LSCIE1
209 .LSCIE1:
210 .long 0x0
211 .byte 0x1
212 .string "zP"
213 .uleb128 0x1
214 .sleb128 -4
215 .byte 0x8
216 .uleb128 0x5
217 .byte 0x0
218 .long __gxx_personality_v0
219 .byte 0xc
220 .uleb128 0x4
221 .uleb128 0x4
222 .byte 0x88
223 .uleb128 0x1
224 .align 4
225 .LECIE1:
226 .LSFDE5:
227 .long .LEFDE5-.LASFDE5
228 .LASFDE5:
229 .long .LASFDE5-.Lframe1
230 .long .LFB1411
231 .long .LFE1411-.LFB1411
232 .uleb128 0x0
233 .byte 0x4
234 .long .LCFI4-.LFB1411
235 .byte 0xe
236 .uleb128 0x8
237 .byte 0x85
238 .uleb128 0x2
239 .byte 0x4
240 .long .LCFI5-.LCFI4
241 .byte 0xd
242 .uleb128 0x5
243 .align 4
244 .LEFDE5:
245 .LSFDE7:
246 .long .LEFDE7-.LASFDE7
247 .LASFDE7:
248 .long .LASFDE7-.Lframe1
249 .long .LFB1413
250 .long .LFE1413-.LFB1413
251 .uleb128 0x0
252 .byte 0x4
253 .long .LCFI7-.LFB1413
254 .byte 0xe
255 .uleb128 0x8
256 .byte 0x85
257 .uleb128 0x2
258 .byte 0x4
259 .long .LCFI8-.LCFI7
260 .byte 0xd
261 .uleb128 0x5
262 .align 4
263 .LEFDE7:
264 .LSFDE9:
265 .long .LEFDE9-.LASFDE9
266 .LASFDE9:
267 .long .LASFDE9-.Lframe1
268 .long .LFB1412
269 .long .LFE1412-.LFB1412
270 .uleb128 0x0
271 .byte 0x4
272 .long .LCFI10-.LFB1412
273 .byte 0xe
274 .uleb128 0x8
275 .byte 0x85
276 .uleb128 0x2
277 .byte 0x4
278 .long .LCFI11-.LCFI10
279 .byte 0xd
280 .uleb128 0x5
281 .align 4
282 .LEFDE9:
283 .LSFDE11:
284 .long .LEFDE11-.LASFDE11
285 .LASFDE11:
286 .long .LASFDE11-.Lframe1
287 .long .LFB1402
288 .long .LFE1402-.LFB1402
289 .uleb128 0x0
290 .byte 0x4
291 .long .LCFI13-.LFB1402
292 .byte 0xe
293 .uleb128 0x8
294 .byte 0x85
295 .uleb128 0x2
296 .byte 0x4
297 .long .LCFI14-.LCFI13
298 .byte 0xd
299 .uleb128 0x5
300 .align 4
301 .LEFDE11:
302 .LSFDE13:
303 .long .LEFDE13-.LASFDE13
304 .LASFDE13:
305 .long .LASFDE13-.Lframe1
306 .long .LFB1403
307 .long .LFE1403-.LFB1403
308 .uleb128 0x0
309 .byte 0x4
310 .long .LCFI16-.LFB1403
311 .byte 0xc
312 .uleb128 0x1
313 .uleb128 0x0
314 .byte 0x9
315 .uleb128 0x4
316 .uleb128 0x1
317 .byte 0x4
318 .long .LCFI17-.LCFI16
319 .byte 0xc
320 .uleb128 0x4
321 .uleb128 0x4
322 .byte 0x4
323 .long .LCFI18-.LCFI17
324 .byte 0xe
325 .uleb128 0x8
326 .byte 0x85
327 .uleb128 0x2
328 .byte 0x4
329 .long .LCFI19-.LCFI18
330 .byte 0xd
331 .uleb128 0x5
332 .byte 0x4
333 .long .LCFI20-.LCFI19
334 .byte 0x84
335 .uleb128 0x3
336 .align 4
337 .LEFDE13:
338 .LSFDE15:
339 .long .LEFDE15-.LASFDE15
340 .LASFDE15:
341 .long .LASFDE15-.Lframe1
342 .long .LFB1401
343 .long .LFE1401-.LFB1401
344 .uleb128 0x0
345 .byte 0x4
346 .long .LCFI22-.LFB1401
347 .byte 0xe
348 .uleb128 0x8
349 .byte 0x85
350 .uleb128 0x2
351 .byte 0x4
352 .long .LCFI23-.LCFI22
353 .byte 0xd
354 .uleb128 0x5
355 .align 4
356 .LEFDE15:
357 .ident "GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)"
358 .section .note.GNU-stack,"",@progbits
359
上面可以看到编译阶段的调用也是通过对重载函数的别名来实现的。

总结:

1.const重载主要是通过能否对传入的参数进行修改为判断的。

2.const参数重载和const函数重载机制都是一样的,因为对于const 函数重载可看做是对隐含的指针this的参数重载。

3.重载是在编译阶段已经完成,对于汇编和链接来说透明的。

 

posted @ 2010-10-21 13:53  博水  阅读(5739)  评论(6编辑  收藏  举报