博文
boost conrersion library(2007-08-03 16:14:00)
摘要:一、与多态类型相关的转换
1、 polymorphic_cast与dynamic_cast
dynamic_cast可以安全地将一个指向多态对象的指针向下转换为派生类指针。但是,当dynamic_cast转换失败时,返回的是NULL,也就是说,dynamic_cast的转换成功与否是在运行期确定,而不像其他C++内建cast那样在编译期确定。换言之,如果在进行dynamic_cast之后,不检测返回值,就等于埋下了一个定时炸弹。
而Boost的polymorphic_cast在dynamic_cast的基础上增加了对返回值的检测,如果转换失败,它就会抛出std::bad_cast。
2、 polymorphic_downcast与dynamic_cast
但是抛出异常会降低程序的效率,而且dynamic_cast更会查询一个type_info结构来确定正确的类型,所以不管是空间上的成本还是时间上的成本,都会大大增加。
polymorphic_downcast可以把成本降低到最低,甚至是编译期上。不过使用这个转换必须非常的小心。
//#define NDEBUG
#include
using namespace std;
struct A{
virtual ~A(){}
};
class B:public A{};
class C:public A{};
int main(){
A *pa=new C;
B *pb=polymorphic_downcast(pa);
}
注意上面没有定义NDEBUG(或编译器的调式模式),这样才能在调试时,判断polymorphic_downcast是否成功。最后,当一切OK的时候,再将定义NDEBUG(或关闭编译器的调试模式)。这样在最终的软件中,polymorphic_downcast即保证了安全的转换,又保证了低运行成本。
3、 窥其内部
template
inline Target polymorphic_cast(Source*x){
Target tmp = dynamic_cast(x);
if ( tmp == ......
用标准c++实现string与各种类型的转换(2007-08-03 15:30:00)
摘要: 要实现这个目标,非stringstream类莫属。这个类在头文件中定义,
< sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。简单起见,我主要以stringstream为中心,因为每个转换都要涉及到输入和输出操作。示例1示范怎样使用一个stringstream对象进行从
string到int类型的转换
注意,使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。
示例1:
std::stringstream stream;
string result="10000";
int n = 0;
stream > n;//n等于10000
int到string类型的转换
string result;
int n = 12345;
stream ......
su和sudo的区别(2007-08-03 09:52:00)
摘要:su和sudo的区别与使用
一. 使用 su 命令临时切换用户身份
1、su 的适用条件和威力
su命令就是切换用户的工具,怎么理解呢?比如我们以普通用户beinan登录的,但要添加用户任务,执行useradd ,beinan用户没有这个权限,而这个权限恰恰由root所拥有。解决办法无法有两个,一是退出beinan用户,重新以root用户登录,但这种办法并不是最好的;二是我们没有必要退出beinan用户,可以用su来切换到root下进行添加用户的工作,等任务完成后再退出root。我们可以看到当然通过su 切换是一种比较好的办法;
通过su可以在用户之间切换,如果超级权限用户root向普通或虚拟用户切换不需要密码,什么是权力?这就是!而普通用户切换到其它任何用户都需要密码验证;
2、su 的用法:
su [OPTION选项参数] [用户]
-, -l, --login 登录并改变到所切换的用户环境;
-c, --commmand=COMMAND 执行一个命令,然后退出所切换到的用户环境;
至于更详细的,请参看man su ;
3、su 的范例:
su 在不加任何参数,默认为切换到root用户,但没有转到root用户家目录下,也就是说这时虽然是切换为root用户了,但并没有改变root登录环境;用户默认的登录环境,可以在/etc/passwd 中查得到,包括家目录,SHELL定义等;
[beinan@localhost ~] $ suPassword:[root@localhost beinan]# pwd/home/beinan
su 加参数 - ,表示默认切换到root用户,并且改变到root用户的环境;
[beinan@localhost ~] $ pwd/home/beinan[beinan@localhost ~] $ su -Password:[root@localhost ~]# pwd/root
su 参数 - 用户名
[beinan@localhost ~] $ su - root 注:这个和su -......
GNU make的用法介绍(2007-07-30 15:45:00)
摘要:) 介绍
~~~~~~~~~~~~~~~
本文将首先介绍为什么要将你的C源代码分离成几个合理的独立档案,什么时候需要
分,怎么才能分的好。然后将会告诉你 GNU Make 怎样使你的编译和连接步骤自动化。
对于其它 Make 工具的用户来说,虽然在用其它类似工具时要做适当的调整,本文的内
容仍然是非常有用的。如果对你自己的编程工具有怀疑,可以实际的试一试,但请先阅
读用户手册。
1) 多文件项目
~~~~~~~~~~~~~~~~~~~~~~
1.1为什么使用它们?
首先,多文件项目的好处在那里呢?
它们看起来把事情弄的复杂无比。又要 header 文件,又要 extern 声明,而且如果需
要查找一个文件,你要在更多的文件里搜索。
但其实我们有很有力的理由支持我们把一个项目分解成小块。当你改动一行代码,编译
器需要全部重新编译来生成一个新的可执行文件。但如果你的项目是分开在几个小文件
里,当你改动其中一个文件的时候,别的源文件的目标文件(object files)已经存在,
所以没有什么原因去重新编译它们。你所需要做的只是重现编译被改动过的那个文件,
然后重新连接所有的目标文件罢了。在大型的项目中,这意味着从很长的(几分钟到几
小时)重新编译缩短为十几,二十几秒的简单调整。
只要通过基本的规划,将一个项目分解成多个小文件可使你更加容易的找到一段代码。
很简单,你根据代码的作用把你的代码分解到不同的文件里。当你要看一段代码时,你
可以准确的知道在那个文件中去寻找它。
从很多目标文件生成一个程序包 (Library)比从一个单一的大目标文件生成要好的多。
当然实际上这是否真是一个优势则是由你所用的系统来决定的。但是当使用 gcc/ld
(一个 GNU C 编译/连接器) 把一个程序包连接到一个程序时,在连接的过程中,它会
尝试不去连接没有使用到的部分。但它每次只能从程序包中把一个完整的目标文件排除
在外。因此如果你参考一个程序包中某一个目标档中任何一个符号的话,那么这个目标
文件整个都会被连接进来。要是一个程序......
六大方法做优秀程序员(2007-07-26 23:01:00)
摘要:本文原作者结合自身经历,总结以下六种方法,可以帮助我们成为一名更好的开发者。
1. 交谈
尽可能多地跟其他软件开发者交谈;培养个人关系;跟意见与你相左的人交流;跟经验更丰富的人交流;跟阅历丰富的人交流。多到Groups 中去,尤其是交谈自由随意的Groups——不约束主题,不约束交谈内容。
2. 选择更好的环境
我遇到好多开发者,在我看来他们有成为优秀开发者的所有优点,只是他们没有机会在好的环境中工作。这里所说的好的环境,是指周围有一帮愿意且能够分享他们知识的开发者。如果你是“菜鸟级”开发者,你的成长路线将因他们而大为缩短;如果你是“高级”开发者,你的能力也会因为同伴的刺激和挑战而提高。
我之前就是在一个非常糟糕的小店打工,钱挣得不少,却是无法提升能力的地方。后来我冒险般地决定去了一家咨询公司,在那里我遇到了很多优秀的开发者。虽然这次换工作给我的家庭和个人来说并没有多大好处,但它给我的职业生涯带来了巨大的发展动力。
3. 参与开源
也许你的工作会枯燥,甚至不合你的兴趣,你也从未从你的开发中得到乐趣。那么,你该参与一个开源项目了。
你可以选择你感兴趣的项目和技术,选择能促使你提高开发技能、让你尝试全新开发思路的项目,而且更为可贵的是,很多都是免费的。搞不好,还能赚点外快呢。
4. 写博客
我曾不止一次地告诉我的妻子,我职业道路上一直在做的唯一一件明智的事情就是写博客。写博客,尤其是观点争论性质的博客,会帮助你整理最近一段时间的思考,没有什么比自己表达自己更引发思考的了,尤其是当有成百上千人读你博客的时候。
5. 多浏览
博客圈中有丰富的资源,自由而免费。除了自己写,多浏览甚至留言跟他们争论都是提高自己很好的方法。
6. 扩大阅读面
保持RSS订阅的平衡性。以前我订阅的技术类几乎全是敏捷开发的,但是最近我扩大了阅读面......
程序员更喜欢Firefox 市场份额超过IE两倍(2007-07-26 22:48:00)
摘要:【CSDN独家报道】浏览器市场激烈的血战从来就没有停止过,虽然微软一直声称IE占据全球浏览器市场份额的78%,但是,根据最近在CSDN的一份调查报告中显示,使用Firefox的人数比例已经远远超过了IE7.0,参与这次调查的人数截止到今天达到了1710人,其中38.62%的人使用FireFox、34.98%的人使用Maxthon、15.29%的人使用IE7.0、6.88%的人使用Opera、4.12%的人使用腾讯的TT。
如图所示:
比例图:
虽然这次参与调查的多数是软件开发人员或者多数是IT从业人员,但是从这一比例我们不难看出,IE丢失掉了曾经在浏览器大战中占据了的技术优势,在IE6推出后的5年时间里,浏览器一直在快速发展,而IE却一直没有更新过,这对一个世界上最常用的产品来说绝对是致命的。Firefox以它的小巧、安全,很容易扩展和定制的特长获得了越来越多的喜爱。
更重要的是,它是是一个自由的浏览器,所有的源代码都是开放的,任何人可以为它的成长贡献力量。Cookie、页面缓存,个人都可以精确的控制,这些特性都是技术人员们所崇尚的“我的地盘 我做主”的精神。
为此,我们也专门采访了国内某著名技术门户网站的技术人员小武,他对于FireFox的喜爱程度溢于言表,相对于IE来说,他认为FireFox是“相当的好用”,比如FireFox可以只显示网页中的某一部分代码,又比如FireFox里面的“捉虫”工具很好用,而且FireFox小巧精悍,对CSS和脚本的支持也非常得人心。
不过我们采访的另一位网站架构师却认为,如果说之前FireFox相对IE6有50%的优势的话,那么,FireFox相对于现在的IE7的优势已经降低到25%左右了。因为IE7从底层已经做了很多的修改,已经慢慢的向W3C标准靠近了许多,在功能使用方面与FireFox的差距也变得很细微,Tab功能,CSS和脚本支持功能现在IE7都比之前表现强了,差距仅仅存在于某些小细节中了。
IE6在这个市场中存在了5年之后微软才意识到改变和向国际标准靠拢的重要性,这就直接导致了像小武这样的大量的技术人员失去了对IE的信心,投向FireFox阵营,不过,微软到底还是......
引用总结(2007-07-26 16:19:00)
摘要:什么是“引用”?申明和使用“引用”要注意哪些问题?
引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。
申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。
2. 将“引用”作为函数参数有哪些特点?
(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
3 在什么时候需要使用“常引用”?
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名;
例1
int a ;
const int &ra=a;
ra=1; //错误
a=1; //正确
例2
string foo( );
void bar(string & s);
那么下面的表达式将是非法的:
bar(foo( ));
bar("hello world");
原因在于foo( )和"hello world"串都会产生一个临时对象,而在C++中,这些临时对象都......
explicit关键字的作用(2007-07-26 16:13:00)
摘要:c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?
如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
class MyClass
{
public:
MyClass( int num );
}
....
MyClass obj = 10; //ok,convert int to MyClass在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
MyClass temp(10);
MyClass obj = temp;上面的所有的操作即是所谓的"隐式转换"。
如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编译通过了,如下所示:
class MyClass
{
public:
explicit MyClass( int num );
}
....
MyClass obj = 10; //err,can't non-explict convert......
c++强制类型转换小结(2007-07-24 23:16:00)
摘要:
标准c++中主要有四种强制转换类型运算符:
const_cast,reinterpret_cast,static_cast,dynamic_cast等等。
1)static_cast<T>(a)
将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型。
表达式static_cast< T > ( a ) a的值转换为模板中指定的类型T。在运行时转换过程中,不进行类型检查来确保转换的安全性。
例子:
class B { ... };
class D : public B { ... };
void f(B* pb, D* pd)
{
D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是B的指针
B* pb2 = static_cast<B*>(pd); // 安全的
...
}
2)dynamic_cast<T>(a)
完成类层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。
表达式dynamic_cast< T >( a ) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。
例子:
class A { ... };
class B { ... };
void f()
{
A* pa = new A;
B* pb = new B;
void* pv = dynamic_cast<void*>(pa);
// pv 现在指向了一个类型为A的对象
...
pv = dynamic......
bool型的用法(2007-07-18 16:40:00)
摘要:布尔型对象可以被赋以文字值true 或false 例如
// 初始化一个string 对象用来存放搜索的结果
string search_word = get_word();
// 把一个bool 变量初始化为false
bool found = false;
string next_word;
while ( cin >> next_word )
if ( next_word == search_word )
found = true;
// ...
// 缩写, 相当于: if ( found == true )
if ( found )
cout << "ok, we found the word\n";
else cout << "nope, the word was not present.\n";
虽然布尔类型的对象也被看作是一种整数类型的对象但是它不能被声明为signed
unsigned short 或long 例如下列代码是非法的
// 错误不能指定bool 为short
short bool found = false;
当表达式需要一个算术值时布尔对象(如found)和布尔文字都被隐式地提升成 int(正
如下面的例子) false 变成0 而true 变成1 例如
bool found = false;
int occurrence_count = 0;
while ( /* 条件省略 */ )
{
found = look_for( /* 内容省略 */ );
// found 的值被提升为0 或者1
occurrence_count += found;
}
正如文字false 和true 能自动转换成整数值0 和1 一样如果有必要算术值和指针值也能隐式地被转换成布尔类型的值0 或空指针被转换成false 所有其他的值都被转换成true
例如
// 返回出现次数
extern int find( const string& );
bool found = false;
if ( found = find......