﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Xiaobo Sun -随笔分类-C++</title><link>http://www.blogjava.net/sunxiaobo/category/35092.html</link><description>Eclipse-Unix
http://umlfact.berlios.de/~s_xsun/</description><language>zh-cn</language><lastBuildDate>Wed, 19 Aug 2009 20:16:59 GMT</lastBuildDate><pubDate>Wed, 19 Aug 2009 20:16:59 GMT</pubDate><ttl>60</ttl><item><title>void* (like Object in Java)</title><link>http://www.blogjava.net/sunxiaobo/archive/2009/02/05/253448.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Thu, 05 Feb 2009 13:07:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2009/02/05/253448.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/253448.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2009/02/05/253448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/253448.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/253448.html</trackback:ping><description><![CDATA[void &nbsp; *从本质上讲是一种指针的类型，就像 &nbsp; (char &nbsp; *)、(int &nbsp; *)类型一样.但是其又具有 &nbsp; <br />
&nbsp; 特殊性，它可以存放其他任何类型的指针类型：例如： &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; char &nbsp; *array="I &nbsp; am &nbsp; the &nbsp; pointer &nbsp; of &nbsp; string"; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; void &nbsp; * &nbsp; temp； &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; //temp可以存放其他任何类型的指针(地址） &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; temp=array; &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; // &nbsp; temp &nbsp; 的指针类型 &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; cout&lt;&lt;array&lt;&lt;endl; &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; cout&lt;&lt;temp&lt;&lt;endl; &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; cout&lt;&lt;(char &nbsp; *)temp&lt;&lt;endl; &nbsp; <br />
&nbsp; 运行结果： &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; I &nbsp; am &nbsp; the &nbsp; pointer &nbsp; of &nbsp; string &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; 0x0042510C &nbsp; （这个值就是array指针变量所存储的值） &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; I &nbsp; am &nbsp; the &nbsp; pointer &nbsp; of &nbsp; string &nbsp; <br />
&nbsp;  &nbsp; <br />
&nbsp;  &nbsp; <br />
&nbsp;  &nbsp; <br />
&nbsp; 2.但是不能将void*类型的值赋给其他既定的类型，除非经过显示转换： &nbsp; 例如： &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; int &nbsp; a=20; &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; int &nbsp; * &nbsp; pr=&amp;a; &nbsp; <br />
&nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp;  &nbsp; void &nbsp; *p; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
pr=p &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //error,不能将空的类型赋给int &nbsp; * &nbsp; <br />
&nbsp;
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pr=(int &nbsp;
*)p; &nbsp; &nbsp; //ok，经过转换&nbsp;
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/253448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2009-02-05 21:07 <a href="http://www.blogjava.net/sunxiaobo/archive/2009/02/05/253448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>extern</title><link>http://www.blogjava.net/sunxiaobo/archive/2008/10/30/237689.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Thu, 30 Oct 2008 12:36:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/10/30/237689.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/237689.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/10/30/237689.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/237689.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/237689.html</trackback:ping><description><![CDATA[<strong>1 基本解释</strong><br />
<br />
extern可以置于变量或者函数前，以标示变量或者函数的定义在别的文件中，提示编译器遇到此变量和函数时在其他模块中寻找其定义。<br />
<br />
另外，extern也可用来进行链接指定。<br />
<strong>2 问题：extern 变量</strong><br />
<br />
在一个源文件里定义了一个数组：<br />
<br />
<table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%">
    <tbody>
        <tr>
            <td>char a[6];</td>
        </tr>
    </tbody>
</table>
<br />
在另外一个文件里用下列语句进行了声明：<br />
<br />
<table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%">
    <tbody>
        <tr>
            <td>extern char *a；</td>
        </tr>
    </tbody>
</table>
<br />
请问，这样可以吗？ <br />
<br />
答案与分析：<br />
<br />
1)、不可以，<a href="http://dev.yesky.com/" class="bluekey" target="_blank">程序</a>运行时会告诉你非法访问。原因在于，指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组，因此与实际的定义不同，从而造成运行时非法访问。应该将声明改为extern char a[ ]。<br />
<br />
2)、例子分析如下，如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值)，*a显然没有意义，如下图：<br />
<br />
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/175021.gif';" src="http://www.yesky.com/image20010518/175021.gif" alt="" align="center" border="1" vspace="1" hspace="3" /></div>
            </td>
        </tr>
    </tbody>
</table>
<br />
显然a指向的空间（0x61626364）没有意义，易出现非法内存访问。<br />
<br />
3)、这提示我们，在使用extern时候要严格对应声明时的格式，在实际编程中，这样的错误屡见不鲜。<br />
<br />
4)、extern用在变量声明中常常有这样一个作用，你在*.c文件中声明了一个全局的变量，这个全局的变量如果要被引用，就放在*.h中并用extern来声明。<br />
<br />
<strong>3 问题：extern 函数1</strong><br />
<br />
常常见extern放在函数的前面成为函数声明的一部分，那么，C语言的关键字extern在函数的声明中起什么作用？<br />
<br />
答案与分析：<br />
<br />
如果函数的声明中带有关键字extern，仅仅是暗示这个函数可能在别的源文件里定义，没有其它作用。即下述两个函数声明没有明显的区别：<br />
<br />
<table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%">
    <tbody>
        <tr>
            <td>extern int f(); 和int f();</td>
        </tr>
    </tbody>
</table>
<br />
当然，这样的用处还是有的，就是在程序中取代include &#8220;*.h&#8221;来声明函数，在一些复杂的项目中，我比较习惯在所有的函数声明前添加extern修饰。<br />
<br />
<strong>4 问题：extern 函数2</strong><br />
&nbsp;<br />
当函数提供方单方面修改函数原型时，如果使用方不知情继续沿用原来的extern申明，这样编译时编译器不会报错。但是在运行过程中，因为少了或者多了输入参数，往往会照成系统错误，这种情况应该如何解决？<br />
<br />
答案与分析：<br />
<br />
目前业界针对这种情况的处理没有一个很完美的方案，通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明，然后调用方include该头文件，从而省去extern这一步。以避免这种错误。<br />
<br />
宝剑有双锋，对extern的应用，不同的场合应该选择不同的做法。<br />
===============================================================================<br />
4.extern "C"的惯用法 <br />
<br />
（1）在C++中引用C语言中的函数和变量，在包含C语言头文件（假设为cExample.h）时，需进行下列处理： <br />
<br />
extern "C" <br />
{ <br />
#include "cExample.h" <br />
} <br />
<br />
<br />
而在C语言的头文件中，对其外部函数只能指定为extern类型，C语言中不支持extern "C"声明，在.c文件中包含了extern "C"时会出现编译语法错误。 <br />
<br />
笔者编写的C++引用C函数例子工程中包含的三个文件的源代码如下： <br />
<dl class="code"><dt>C/C++ code</dt><dd>
<pre>
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><span style="color: #000000;"><br />
<br />
</span><span style="color: #008000;">/*</span><span style="color: #008000;"> c语言头文件：cExample.h </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
#ifndef C_EXAMPLE_H<br />
<br />
</span><span style="color: #0000ff;">#define</span><span style="color: #000000;"> C_EXAMPLE_H</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">extern</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> add(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> x,</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> y);<br />
<br />
</span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #008000;">/*</span><span style="color: #008000;"> c语言实现文件：cExample.c </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
#include </span><span style="color: #800000;">"</span><span style="color: #800000;">cExample.h</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> add( </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> x, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> y )<br />
<br />
{<br />
<br />
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> x </span><span style="color: #000000;">+</span><span style="color: #000000;"> y;<br />
<br />
}<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;"> c++实现文件，调用add：cppFile.cpp</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #0000ff;">extern</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
<br />
{<br />
<br />
#include </span><span style="color: #800000;">"</span><span style="color: #800000;">cExample.h</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
<br />
}<br />
<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> argc, </span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;"> argv[])<br />
<br />
{<br />
<br />
add(</span><span style="color: #800080;">2</span><span style="color: #000000;">,</span><span style="color: #800080;">3</span><span style="color: #000000;">);<br />
<br />
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #800080;">0</span><span style="color: #000000;">;<br />
<br />
}<br />
<br />
<br />
<br />
<br />
<br />
如果C</span><span style="color: #000000;">++</span><span style="color: #000000;">调用一个C语言编写的.DLL时，当包括.DLL的头文件或声明接口函数时，应加extern </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;"> {　}。<br />
<br />
<br />
<br />
（</span><span style="color: #800080;">2</span><span style="color: #000000;">）在C中引用C</span><span style="color: #000000;">++</span><span style="color: #000000;">语言中的函数和变量时，C</span><span style="color: #000000;">++</span><span style="color: #000000;">的头文件需添加extern </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;">，但是在C语言中不能直接引用声明了extern </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;">的该头文件，应该仅将C文件中将C</span><span style="color: #000000;">++</span><span style="color: #000000;">中定义的extern </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;">函数声明为extern类型。<br />
<br />
笔者编写的C引用C</span><span style="color: #000000;">++</span><span style="color: #000000;">函数例子工程中包含的三个文件的源代码如下：<br />
<br />
<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">C++头文件 cppExample.h</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #000000;">#ifndef CPP_EXAMPLE_H<br />
<br />
</span><span style="color: #0000ff;">#define</span><span style="color: #000000;"> CPP_EXAMPLE_H</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">extern</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> add( </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> x, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> y );<br />
<br />
</span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">C++实现文件 cppExample.cpp</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #000000;">#include </span><span style="color: #800000;">"</span><span style="color: #800000;">cppExample.h</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> add( </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> x, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> y )<br />
<br />
{<br />
<br />
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> x </span><span style="color: #000000;">+</span><span style="color: #000000;"> y;<br />
<br />
}<br />
<br />
</span><span style="color: #008000;">/*</span><span style="color: #008000;"> C实现文件 cFile.c<br />
<br />
/* 这样会编译出错：#include "cExample.h" </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">extern</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> add( </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> x, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> y );<br />
<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main( </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> argc, </span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;"> argv[] )<br />
<br />
{<br />
<br />
add( </span><span style="color: #800080;">2</span><span style="color: #000000;">, </span><span style="color: #800080;">3</span><span style="color: #000000;"> );<br />
<br />
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #800080;">0</span><span style="color: #000000;">;<br />
<br />
}</span></div>
<br />
<br />
<br />
</pre>
</dd></dl><br />
<br />
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/237689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-10-30 20:36 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/10/30/237689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ref as function param</title><link>http://www.blogjava.net/sunxiaobo/archive/2008/10/23/236239.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Thu, 23 Oct 2008 11:15:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/10/23/236239.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/236239.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/10/23/236239.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/236239.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/236239.html</trackback:ping><description><![CDATA[常引用<br />
<br />
常引用声明方式：const 类型标识符 &amp;引用名=目标变量名；<br />
用这种方式声明的引用，不能通过引用对目标变量的值进行修改,从而使引用的目标成为<br />
const，达到了引用的安全性。<br />
【例3】：<br />
int a ;<br />
const int &amp;ra=a;<br />
ra=1; //错误<br />
a=1; //正确<br />
这不光是让代码更健壮，也有些其它方面的需要。<br />
【例4】：假设有如下函数声明：<br />
string foo( );<br />
void bar(string &amp; s);<br />
那么下面的表达式将是非法的：<br />
bar(foo( ));<br />
bar("hello world");<br />
原因在于foo( )和"hello world"串都会产生一个临时对象，而在C++中，这些临时对象都是<br />
const 类型的。因此上面的表达式就是试图将一个const 类型的对象转换为非const 类型，<br />
这是非法的。<br />
引用型参数应该在能被定义为const 的情况下，尽量定义为const 。<br />
<br />
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/236239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-10-23 19:15 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/10/23/236239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pkg-config学习 </title><link>http://www.blogjava.net/sunxiaobo/archive/2008/10/15/234504.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Wed, 15 Oct 2008 11:12:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/10/15/234504.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/234504.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/10/15/234504.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/234504.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/234504.html</trackback:ping><description><![CDATA[<h2><a href="http://study.lijie.org/post/18769949/pkg-config"><br />
</a></h2>
&nbsp;首先说下/etc/ld.so.conf:<br />
<br />
这个文件记录了编译时使用的动态链接库的路径。<br />
默认情况下，编译器只会使用/lib和/usr/lib这两个目录下的库文件<br />
如果你安装了某些库，比如在安装gtk+-2.4.13时它会需要glib-2.0 &gt;= 2.4.0,辛苦的安装好glib后<br />
没有指定 —prefix=/usr 这样glib库就装到了/usr/local下，而又没有在/etc/ld.so.conf中添加/usr/local/lib这个搜索路径，所以编译gtk+-2.4.13就会出错了 对于这种情况有两种方法解决：<br />
一：在编译glib-2.4.x时，指定安装到/usr下，这样库文件就会放在/usr/lib中，gtk就不会找不到需要的库文件了 对于安装库文件来说，这是个好办法，这样也不用设置PKG_CONFIG_PATH了<br />
<br />
二：将/usr/local/lib加入到/etc/ld.so.conf中，这样安装gtk时就会去搜索/usr/local/lib,同样可以找到需要的库<br />
将/usr/local/lib加入到/etc/ld.so.conf也是必须的，这样以后安装东东到local下，就不会出现这样的问题了。<br />
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择<br />
添加方法也极其简单，将库文件的绝对路径直接写进去就OK了，一行一个。例如：<br />
/usr/X11R6/lib<br />
/usr/local/lib<br />
/opt/lib<br />
<br />
再来看看ldconfig ：<br />
<br />
它是一个程序，通常它位于/sbin下，是root用户使用的。具体作用及用法可以man ldconfig查到<br />
简单的说，它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用<br />
因此当安装完一些库文件，(例如刚安装好glib)，或者修改ld.so.conf增加新的库路径后，需要运行一下/sbin/ldconfig<br />
使所有的库文件都被缓存到ld.so.cache中，如果没做，即使库文件明明就在/usr/lib下的，也是不会被使用的，结果编译过程中报错，缺少xxx库<br />
我曾经编译KDE时就犯过这个错误，(它需要每编译好一个东东，都要运行一遍)，所以切记改动库文件后一定要运行一下ldconfig，在任何目录下运行都可以。<br />
<br />
再来说说 PKG_CONFIG_PATH这个变量吧:<br />
<br />
经常在论坛上看到有人问&#8221;为什么我已经安装了glib-2.4.x，但是编译gtk+-2.4.x 还是提示glib版本太低阿？<br />
为什么我安装了glib-2.4.x，还是提示找不到阿？。。。。。。&#8221;都是这个变量搞的鬼。<br />
先说说它是哪冒出来的，当安装了pkgconfig-x.x.x这个包后，就多出了pkg-config，它就是需要PKG_CONFIG_PATH的东东<br />
pkgconfig-x.x.x又是做什么的？ 来看一段说明：<br />
<br />
The pkgconfig package contains tools for passing the include path
and/or library paths to build tools during the make file execution.<br />
<br />
pkg-config is a function that returns meta information for the specified library.<br />
<br />
The default setting for PKG_CONFIG_PATH is /usr/lib/pkgconfig because
of the prefix we use to install pkgconfig. You may add to
PKG_CONFIG_PATH by exporting additional paths on your system where
pkgconfig files are installed. Note that PKG_CONFIG_PATH is only needed
when compiling packages, not during run-time.<br />
<br />
其实pkg-config就是向configure程序提供系统信息的程序，比如软件的版本啦，库的版本啦，库的路径啦，等等<br />
这些信息只是在编译其间使用。你可以 ls /usr/lib/pkgconfig 下，会看到许多的*.pc,用文本编辑器打开<br />
会发现类似下面的信息：<br />
<br />
prefix=/usr<br />
exec_prefix=${prefix}<br />
libdir=${exec_prefix}/lib<br />
includedir=${prefix}/include<br />
<br />
glib_genmarshal=glib-genmarshal<br />
gobject_query=gobject-query<br />
glib_mkenums=glib-mkenums<br />
<br />
Name: GLib<br />
Description: C Utility Library<br />
Version: 2.4.7<br />
Libs: -L${libdir} -lglib-2.0<br />
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include<br />
<br />
明白了吧，configure就是靠这些信息判断你的软件版本是否符合要求。并且得到这些东东所在的位置，要不去哪里找呀。<br />
不用我说你也知道为什么会出现上面那些问题了吧。<br />
<br />
解决的办法很简单，设定正确的PKG_CONFIG_PATH，假如将glib-2.x.x装到了/usr/local/下，那么glib-2.0.pc就会在<br />
/usr/local/lib/pkgconfig下，将这个路径添加到PKG_CONFIG_PATH下就可以啦。并且确保configure找到的是正确的<br />
glib-2.0.pc,就是将其他的lib/pkgconfig目录glib-2.0.pc干掉就是啦。(如果有的话 ^-^)<br />
设定好后可以加入到~/.bashrc中，例如：<br />
PKG_CONFIG_PATH=/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:<br />
/usr/X11R6/lib/pkgconfig<br />
[root@NEWLFS ~]#echo $PKG_CONFIG_PATH<br />
/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:/usr/X11R6/lib/pkgconfig<br />
<br />
从上面可以看出，安装库文件时，指定安装到/usr，是很有好处的，无论是/etc/ld.so.conf还是PKG_CONFIG_PATH<br />
默认都会去搜索/usr/lib的，可以省下许多麻烦，不过从源码包管理上来说，都装在/usr下<br />
管理是个问题，不如装在/usr/local下方便管理<br />
其实只要设置好ld.so.conf，PKG_CONFIG_PATH路径后，就OK啦
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/234504.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-10-15 19:12 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/10/15/234504.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Makefile example</title><link>http://www.blogjava.net/sunxiaobo/archive/2008/10/09/233437.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Thu, 09 Oct 2008 12:55:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/10/09/233437.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/233437.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/10/09/233437.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/233437.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/233437.html</trackback:ping><description><![CDATA[#libxml2 and glibmm are not neccessary to compile the main.cpp<br />
#macro<br />
libxml2:=../../libxml2<br />
libxml++:=..<br />
glibmm:=../../glibmm<br />
#adds include directives<br />
CC:=g++<br />
CCINCLUDE:= -I$(libxml++)/include/libxml++-2.6 -I$(libxml++)/lib/libxml++-2.6/include "<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -I$(libxml2)/include -I$(glibmm)/include<br />
#linking<br />
LD:=g++<br />
LDSTDLIBS:= -L$(libxml++)/lib -L$(libxml2)/lib -L$(glibmm)/lib<br />
LDLIBS:= -lxml++-2.6<br />
LDLIBFLAGS:= -shared $(LDLIBS) $(LDSTDLIBS)<br />
LDEXEFLAGS:= $(LDSTDLIBS) $(LDLIBS)<br />
#extending library path<br />
#export VAR:=... means make it effective in the subprocess(Makefile)<br />
#export LD_LIBRARY_PATH:=... doesn't work because it's only effective in the subprocesses, not parentprocess(shell)<br />
#therefore the LD_RUN_PATH which allocates dynamic libs to the exe file must be set and export to take effect in the ld cmd<br />
LD_LIBRARY_PATH:=$(libxml++)/lib:$(LD_LIBRARY_PATH)<br />
export LD_RUN_PATH:=$(LD_LIBRARY_PATH)<br />
#list of source files for building the target<br />
SRC:= main.cpp<br />
OBJ:=$(patsubst %.cpp,%.o,$(filter %.cpp,$(SRC)))<br />
#targets<br />
# $^ everyone behinds the : , and $&lt; first one behinds the :<br />
# $(OBJ): %.o: %.cpp is another common implicit rule is for the construction of .o files out of .cpp<br />
.PHONY: all clean<br />
all: $(OBJ)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(LD) $(LDEXEFLAGS) $^ -o $@<br />
<br />
$(OBJ): %.o: %.cpp<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(CC) $(CCINCLUDE) -c $&lt; -o $@<br />
clean:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -f $(OBJ) all *~ \.*.swp<br />
<br />
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/233437.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-10-09 20:55 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/10/09/233437.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gdb</title><link>http://www.blogjava.net/sunxiaobo/archive/2008/08/05/220293.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Tue, 05 Aug 2008 14:42:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/08/05/220293.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/220293.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/08/05/220293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/220293.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/220293.html</trackback:ping><description><![CDATA[&gt;gdb ./sysprocess<br />
(gdb)set args -id 0 -taskcfg ub900proc<br />
(gdb)r //run<br />
Starting program: ../sysprocess -id 0 -taskcfg ub900proc<br />
..<br />
Program received signal SIGSEGV, Segmentation fault.<br />
(gdb)backtrace //打印当前的函数调用栈的所有信息。<br />
(gdb)frame 7 //查看信息，n是一个从0开始的整数，是栈中的层编号<br />
(gdb)up<br />
(gdb)down<br />
(gdb)quit<br />
<br />
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/220293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-08-05 22:42 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/08/05/220293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LD_LIBRARY_PATH</title><link>http://www.blogjava.net/sunxiaobo/archive/2008/06/16/208414.html</link><dc:creator>Xiaobo Sun</dc:creator><author>Xiaobo Sun</author><pubDate>Mon, 16 Jun 2008 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/sunxiaobo/archive/2008/06/16/208414.html</guid><wfw:comment>http://www.blogjava.net/sunxiaobo/comments/208414.html</wfw:comment><comments>http://www.blogjava.net/sunxiaobo/archive/2008/06/16/208414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sunxiaobo/comments/commentRss/208414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sunxiaobo/services/trackbacks/208414.html</trackback:ping><description><![CDATA[vim /etc/ld.so.conf<br />
====================<br />
LD_LIBRARY_PATH: defines the path of dynamic libraries used at the run time<br />
LD_RUN_PATH: at compile time tells the exe file what is path of dynamic libraries used at the run time<br />
======================<br />
ldd exe // show the used dynamic libs<br />
<img src ="http://www.blogjava.net/sunxiaobo/aggbug/208414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sunxiaobo/" target="_blank">Xiaobo Sun</a> 2008-06-16 20:21 <a href="http://www.blogjava.net/sunxiaobo/archive/2008/06/16/208414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>