雕栏玉砌应犹在,只是朱颜改
2008年7月21日 #
2006年11月29日 #
2006年11月10日 #
多吃碱性食物。研究发现,多食碱性食物,可保持血液呈弱碱性,使得血液中乳酸、尿素等酸性物质减少,并能防止其在管壁上沉积,因而有软化血管的作用,故有人称碱性食物为“血液和血管的清洁剂”。这里所说的酸碱性,不是食物本身的性质,而是指食物经过消化吸收后,留在体内元素的性质。常见的酸性元素有氮、碳、硫等;常见的碱性元素有钾、钠、钙、镁等。有的食物口味很酸,如番茄、橘子,却都是地地道道的强碱性食物,因为它们在体内代谢后的最终元素是钾元素等。
何谓酸性或碱性食物 所谓酸性食物或碱性食物,并不是指味道酸或咸的食物,而是指食物经过消化吸收和代谢后产生的阳离子或阴离子占优势的食物。也就是说,某种食物如经代谢后产生的钾、钠、钙、镁等阳离子占优势的则属碱性食物;而代谢后产生磷、氯、硫等阴离子占优势的食物属酸性食物。柠檬、柑桔、杨桃等味道虽酸,但它经代谢后,有机酸变成了水和二氧化碳,后者经肺呼出体外,剩下的阳离子占优势,仍属碱性食物;同理,肉、鱼、蛋类和米面虽无酸味,但代谢后产生的阴离子较多,仍属于酸性食物。因此,不能从食物的味道来区分酸性或碱性食物。看起来挺恐怖的。。。看来得注意下伙食了,以后要多吃水果、蔬菜。。。~~~
2006年10月26日 #
这几天拿到公司以前项目中的一个用C++Builder做的程序,在我机器上调试,结果提示出错:Operation not applicable
使用断点跟踪之后发现错误出在使用TQuery时执行open方法时,回追根源,得出以下反馈:
执行完这句之后,按正常情况,参数PId应该被赋予了一个整形值,但是Debug跟踪显示其值还是跟未赋值前是同样表示的未知值。所以在执行open方法时出错了。
如果我不是用该方法,直接把SQL语句写死:
运行正常
或者用
也运行正常
查了下,原来给参数赋值的方法并没有错误,编译也能通过,况且以前该程序肯定是能正常运行的。。真是奇怪为什么在我这里就赋不上值。。调试了很久也没能找到原因,只好作罢,为了顺利运行,只能改为sprintf和直接连接字符串的方式。在这里记上一笔,希望以后能够找到原因。。。
2006年9月28日 #
本文对我前面几篇随笔中提到的问题也作出了一个总结,感觉很有必要记下来。以上内容原文引用自参考书籍中内容。参考书籍:C++PrimerPlus author:Stephen Prata
以上代码片断中,pc1和pc3为布局new操作符来分配内存,而pc2和pc4为常规new操作符来分配内存 。对于常规new操作符分配的内存,可以直接使用:delete pc2; 这样的语句操作来释放内存。而对于布局new操作符分配的内存就不能这样做:delete pc1;
因为pc1和pc3并没有直接收到new操作符返回的地址,而是由布局操作符指向了buffer的地址,new/delete系统知道已分配的512字节块buffer,但对布局new操作符对该内存块做了何种处理一无所知。另一方面,buffer的地址是用new []初始化的,因此必须使用delete[]而不是delete。注意:即使buffer是使用new而不是new[]初始化的,delete pc1 也将释放buffer,而不是pc1。
以上的代码确实释放了buffer:delete [] buffer;但是由此产生了新的问题,它没有为布局new操作符在该内存块中创建的对象调用析构函数,我们只需要在析构函数中放入一段显示语句就可以清楚的看到,程序并没有销毁“JustTesting”和“Bad Idea”,也就是pc1和pc3指向的对象。那么这里就需要我们显式的为布局new操作符创建的对象调用析构函数。正常情况下将自动调用析构函数,这是需要显示调用析构函数的少数几种情况之一。显式调用析构函数时,必须指定要销毁的对象。由于有指向对象的指针,因此可以这样写:
把这段代码放到delete [] buffer;之前,这段程序才算完整无错。
参考书籍:C++PrimerPlus author:Stephen Prata
在使用new来初始化对象的指针成员时必须特别小心,以下是几点注意事项:
例如有以下class:
在构造函数和析构函数定义当中有如下定义:
那么在程序当中如果有以下代码:
以上的第二条初始化语句将会调用什么构造函数?记住,这种形式的初始化等效于下面的语句:
因为sports的类型为StringBad,因此相应的构造函数原型应该如下:
当我们使用一个对象来初始化另一个对象时,编译器将自动生成上述构造函数(称为复制构造函数,因为它创建对象的一个副本)。现在我们不妨总结一下所谓的隐式成员函数,即C++自动提供了以下这些成员函数:
现在我们来看看我们没有定义复制构造函数的情况下调用隐式复制构造函数将会出现什么情况。从构造函数定义的代码片断可以看到,当中使用new操作符初始化了一个指针str,而隐式的复制构造函数是按值进行复制的,那么对于指针str,将会进行如下复制:
这里复制的不是字符串,而是一个指向字符串的指针!也就是说,我们将得到两个指向同一个字符串的指针!由此会产生的问题将不言而喻。当其中一个对象调用了析构函数之后,其str指向的内存将被释放,这个时候我们如果调用另一个对象,其str指向的地址数据会是什么?很明显将会出现不可预料的结果。
所以由此可见,如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这被称为深度复制。因为默认的浅复制(或成为成员复制)仅浅浅的赋值指针信息。
我们再看以下代码片断,我们稍做修改:
这里的最后一行将与以上例子有所区别,现在是将已有对象赋给另一个已有对象,这将会采取其他操作,即使用重载的赋值操作符。(我们需要知道的是:初始化总是会调用复制构造函数,而使用=操作符时也可能调用赋值操作符)因为C++允许对象赋值,这是通过自动为类重载赋值操作符实现的。其原型如下:
它接受并返回一个指向类对象的引用。与隐式的复制构造函数一样,隐式的对象赋值操作符也会产生同样的问题,即包含了使用new初始化的指针成员时,只会采用浅复制。所以我们需要使用同样的解决办法,即定义一个重载的赋值操作符来实现深度复制。
所以综上所述,如果类中包含了使用new初始化的指针成员,我们应该显式定义一个复制构造函数和一个重载的赋值操作符来实现其深度复制,避免由此带来的成员复制问题参考书籍:C++PrimerPlus author:Stephen Prata
Powered by: C++博客 Copyright © 爱上青菜的包子