歪酷博客
日 历
网志文件夹
· 所有网志
最 新 的 评 论
搜 索
友 情 链 接
· 歪酷博客
· 管理我的Blog

订阅 RSS

0019097

歪酷博客

学习平台


Lhb @ 2004-09-23 23:42

不要轻视拷贝构造函数与赋值函数
版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。


由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数
有些轻视。请先记住以下的警告,在阅读正文时就会多心:
‹ 如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”
的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐
含了错误。以类String 的两个对象a,b 为例,假设a.m_data 的内容为“hello”,
b.m_data 的内容为“world”。
现将a 赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。
这将造成三个错误:一是b.m_data 原有的内存没被释放,造成内存泄露;二是
b.m_data 和a.m_data 指向同一块内存,a 或b 任何一方变动都会影响另一方;三
是在对象被析构时,m_data 被释放了两次。
‹ 拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对
象被创建时调用的,而赋值函数只能被已经存在了的对象调用。以下程序中,第三
个语句和第四个语句很相似,你分得清楚哪个调用了拷贝构造函数,哪个调用了赋
值函数吗?
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成 c(a);
c = b; // 调用了赋值函数
本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。


类String 的拷贝构造函数与赋值函数

// 拷贝构造函数
String::String(const String &other)
{
// 允许操作other 的私有成员m_data
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data, other.m_data);
}
// 赋值函数
String & String:perate =(const String &other)
{
// (1) 检查自赋值
if(this == &other)
return *this;
// (2) 释放原有的内存资源
delete [] m_data;
// (3)分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data, other.m_data);
// (4)返回本对象的引用
return *this;
}
类String 拷贝构造函数与普通构造函数的区别是:在函数入口处无
需与NULL 进行比较,这是因为“引用”不可能是NULL,而“指针”可以为NULL。
类String 的赋值函数比构造函数复杂得多,分四步实现:
(1)第一步,检查自赋值。你可能会认为多此一举,难道有人会愚蠢到写出 a = a 这
样的自赋值语句!的确不会。但是间接的自赋值仍有可能出现,例如
// 内容自赋值
b = a;

c = b;

a = c;

// 地址自赋值
b = &a;

a = *b;
也许有人会说:“即使出现自赋值,我也可以不理睬,大不了化点时间让对象复制
自己而已,反正不会出错!”
他真的说错了。看看第二步的delete,自杀后还能复制自己吗?所以,如果发现自
赋值,应该马上终止函数。注意不要将检查自赋值的if 语句
if(this == &other)
错写成为
if( *this == other)
(2)第二步,用delete 释放原有的内存资源。如果现在不释放,以后就没机会了,将
造成内存泄露。
(3)第三步,分配新的内存资源,并复制字符串。注意函数strlen 返回的是有效字符
串长度,不包含结束符‘{post.abstract}’。函数strcpy 则连‘{post.abstract}’一起复制。
(4)第四步,返回本对象的引用,目的是为了实现象 a = b = c 这样的链式表达。注
意不要将 return *this 错写成 return this 。那么能否写成return other 呢?效果
不是一样吗?
不可以!因为我们不知道参数other 的生命期。有可能other 是个临时对象,在赋
值结束后它马上消失,那么return other 返回的将是垃圾。


偷懒的办法处理拷贝构造函数与赋值函数

如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的
缺省函数,怎么办?
偷懒的办法是:只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。
例如:
class A
{ …
private:
A(const A &a); // 私有的拷贝构造函数
A & operate =(const A &a); // 私有的赋值函数
};
如果有人试图编写如下程序:
A b(a); // 调用了私有的拷贝构造函数
b = a; // 调用了私有的赋值函数
编译器将指出错误,因为外界不可以操作A 的私有函数。


 
Lhb @ 2004-09-23 23:26

下面有三道面试题,想求证一下答案,感兴趣的话帮忙吧答案贴出来看看!

一:
 已知类String的原型为:
 calss String
 {
  public:
      String(const char *str = NULL);            //普通构造函数
      String(const String &copy);                //拷贝构造函数
      ~String(void);                             //析构函数
      String & operator = (const String &copy);  //赋值构造函数
  private:
      char * m_data;                             //用于保存字符串
 };
请编写Sting的上述4个函数:

二:
 该错题,只能在原来的基础上增加代码,不能删除代码
 #include <stdio.h>
 #include <malloc.h>
 void foo(int age,char *b)
{
    b = (char *)malloc(64);
    sprintf(b,"Your Age is %d",age);
}
int main()
{
   char *f;
   foo(23,f);
   printf("%s\n",f);
}


三:有程序片断如下
 int main()
 {
    int I = 20;
    pid_t pid = 5;
    if((pid = fork()) > 0)
    {
       I = 50;
       printf("%d\n",I);   (1)
    }
    else if(pid == 0)
    {
       printf("%d\n",I);   (2)
    }
 }

请问该程序用的是进程方式还是线程方式,并说明进程与线程的区别:
请问该程序输出什么结果?

满分:
第一题解答:
// String 的析构函数
String::~String(void) // 3 分
{
  delete [] m_data;
// 由于m_data 是内部数据类型,也可以写成delete m_data;
}
String::String(const char *str)
{
  if(str==NULL)
 {
  m_data = new char[1]; // 若能加NULL 判断则更好
  *m_data = ‘{post.abstract}’;
  }
 else
  {
  int length = strlen(str);
  m_data = new char[length+1]; // 若能加NULL 判断则更好
  strcpy(m_data, str);
  }
}
// 拷贝构造函数
String::String(const String &other)
{
  int length = strlen(other.m_data);
  m_data = new char[length+1]; // 若能加NULL 判断则更好
  strcpy(m_data, other.m_data);
}
// 赋值函数
String & String:perate =(const String &other)
{
 // (1) 检查自赋值
 if(this == &other)
 return *this;
 // (2) 释放原有的内存资源
 delete [] m_data;
 // (3)分配新的内存资源,并复制内容
  int length = strlen(other.m_data);
 m_data = new char[length+1]; // 若能加NULL 判断则更好
  strcpy(m_data, other.m_data);
 // (4)返回本对象的引用
  return *this;
}




1.  String::String (const char *str)
 {
      if(str){
       memset(m_data,0,strlen(m_data));
       strcpy(m_data,str);
      }
      else *m_data=0;
 }

   String::String (const String &copy)
  {
      strcpy(m_data,copy.m_data);
   }

   String& String:perator =(const String &copy)
  {
     if(this==&copy) retrun *this;
      strcpy(m_data,copy.m_data);
       return *this;
   }

2.  #include <stdio.h>
   #include <malloc.h>
 void foo(int age,char **b)
{
    *b = (char *)malloc(64);
    sprintf(*b,"Your Age is %d",age);
}
int main()
{
   char **f;
   foo(23,f);
   printf("%s\n",**f);
   return 0;
}

3. 不会  :)


lansefeng(兰色风)
1.  String::String (const char *str)
 {
      if ( m_data )
          delete m_data;
      if(str){
       m_data = new char[strlen(str)];
       memset(m_data,0,strlen(m_data));
       strcpy(m_data,str);
      }
      else *m_data=0;
 }

   String::String (const String &copy)
  {
      if ( m_data )
          delete m_data;
      m_data = new char[strlen(copy.m_data)]
      strcpy(m_data,copy.m_data);
   }

   String& String:perator =(const String &copy)
  {
     if(this==&copy) retrun *this;
      if ( m_data )
          delete m_data;
      m_data = new char[strlen(copy.m_data)]
      strcpy(m_data,copy.m_data);
       return *this;
   }
~String::String(void)
{
   if ( m_data )
       delete m_data;
}                     

2、3 不会
对lansefeng(兰色风) 的纠正:
1.delete[] m_data;
2.m_data = new char[strlen(copy.m_data) + 1]; //+1




#include <stdio.h>
 #include <malloc.h>
 void foo(int age,char *&b)
{
    b = (char *)malloc(64);
    sprintf(b,"Your Age is %d",age);
}
int main()
{
   char *f;
   foo(23,f);
   printf("%s\n",f);
}



#include <stdio.h>
#include <malloc.h>
 void foo(int age,char *&b)
{
    b = (char *)malloc(64);
    sprintf(b,"Your Age is %d",age);
}
int main()
{
   char *f;
   foo(23,f);
   printf("%s\n",f);
   free(f);//不要忘了free;
}




 
Lhb @ 2004-09-23 22:16

n个人 编号分别为1,2,3,4....n 坐成一个圈  从1号开始循环数数1,2,3。数到3的人被踢走
写一个算法  得出最后剩下的是几号?


用链表来做把,
谭浩强的C语言上便的习题就有,

西安比斯特出的面试题,我知道。


int n[n+1];
for ( int i = 0; i < n+1; i ++)
 n = i;
i = 1;
int j = 1;
int nReserv = 0;
while ( 1 )
{
   if ( i % 3 )
   {
      n[j] = 0;
      i = 0;
   }
   j ++;
   if ( j > n );
       j = 1;
   if ( n [ j ] != 0 )
   {
      if ( nReserv == j )
          break;
      i++;
      nReserv = j;
   }
}



清华版的“数据结构”中有介绍,好像是在链表那章,具体忘了,只记得当时老师编了个演示程序很好玩,图形界面的,当时老师还说要想作出他那样的程序还要好好学学!!


循环链表做起来应该很简单的吧

数据结构的约瑟夫问题


循环链表,仅供参考:

#include <iostream.h>

struct CircleLink{
   int number;
   CircleLink* next;
};

void createCircleLink(CircleLink* &head, int n)
{
   head = new CircleLink;
   if (head == NULL)
return;
   int count = 1;
   head->number = count++;
   CircleLink *p = head;
   while(count <= n){
CircleLink *q = new CircleLink;
q->number = count++;
p->next = q;
p = q;
   }
   p->next = head;
}

void count3andDel(CircleLink* &head)
{
   CircleLink* find;
   CircleLink* p = head->next;
   find = p->next;
   p->next = find->next;
   delete find;
   head = p->next;
}

int getNumber(CircleLink* head)
{
   CircleLink* p = head->next;
   int count = 1;
   while(p != head){
p = p->next;
count ++;
   }
   return count;
}

void main()
{
   int n;
   cout << "Please input the number of people:\n" << "n=:";
   cin >> n;

   CircleLink *head = NULL;
   createCircleLink(head,n);
   int start = 1;

   while(getNumber(head) > 1){
count3andDel(head);
   }
   cout << "The last one is: " << head->number << endl;
}






 
Lhb @ 2004-09-23 16:49

中国Linux论坛--文章荟萃


文章荟萃首页 | 分类文章 | 搜寻文章  


文章荟萃
  >> 分类FAQ  此话题阅读次数: 7124  上一篇  索引  下一篇  平坦模式  树状模式  




打印  
文章标题   中国Linux论坛《linux入门版》FAQ---qiuluhua[本站会员]  评注  

张贴者: admin (enthusiast)
张贴日期 04/06/02 02:27 AM



原文章发布于 2001.10.12 by qiuluhua[本站会员]


请朋友们在发贴提问之前先看看下面。下面如果没有你需要的内容的话,请出手 .........

一 、Linux学习指导,相当不错的linux入门的文章

希望朋友们看到有关linux入门方面比较不错的文章请跟以下这个贴子:
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=158189

这里已有"无涯子=muyu"老版主提供的一篇入门级的文章 http://www.yesky.com/20010829/194313.shtml

二、linux常见问题解答

1.什么是LINUX?
  LINUX是一个可独立运作的POSIX兼容操作系统,它也包含了SYS V和BSD的功能。
它完全是独之发展的,所以其中没有任何有版权问题的代码。LINUX可以在符合GNU
Public License的情况下自由传播。它的核心是由芬兰人Linus Torvalds
(torvalds@kruuna.helsinki.fi)所写。

2.LINUX的版本
  Linux的版本号分成两部分:内核和发行套件版本。很多人常常把内核的版本号
和发行套件版本号弄混了,实际上内核的版本号是Linus领导下的开发小组开发的内核
的版本号。(通常,内核版本序号是偶数表示是稳定的版本,奇数序号是不稳定的测试版本)

3.LINUX的标准发音
  ftp:/Linux.cis.nctu.edu.tw/pub/kernel/SillySound/english.au,这是Linux
本人的Linux发音的声音文件,应该是最权威的。

4.怎样自己制作boot disk
  rdev /vmlinuz /dev/hda1 (其中/dev/hda1 是系统根挂接点的分区)
dd if=vmlinuz of=/dev/fd0

5.LILO出错信息意义
没有信息 ======> LILO没有安装或者安装LILO的分区没有被激活
LI ======> LILO第一部分被加载,第二部分出错。一般由于LILO定位错误
或者使用了错误的boot.b文件。
LIL ======> LILO第二部分开始加载,但是没有从map文件中成功读取descriptor tables。
LIL? ======> LILO第二部分在错误的地方加载,原因同"LI"。
LIL- ======> descriptor table 错误,或者是改变了boot.B文件却没有重新安装LILO。
LILO ======> LILO的所有部分都安装完毕。
10101010 ======> 如果用户的分区情况改变却没有重新安装LILO,LILO开机时就会出现1010现象。
这时用软盘开机重新运行LILO就可以修复,用户超频的时候也有可能出现这种情况。

6.如何反安装LILO
  用DOS启动,执行FDISK /MBR就可以重写主引导记录,覆盖LILO。
or 在Linux下执行 lilo -u /dev/hda (其中/dev/hda 是lilo安装的位置)

7.如何在LINUX下看WIN95长文件名
  确定核心支持VFAT文件系统,然后改/etc/fstab中的选项,
例如:mount -t vfat /dev/hda1 /dos这样就可以看win95长文件名了。

8.显示彩色目录及文件列表
  用ls --color -F,--color指示用彩色显示,-F会在文件/目录名后加一个字符来指示它的类别。

建议初学者用man ls看看ls的详细使用信息。

比如 -l 列出文件/目录的绝大部分信息(长格式显示);
-a 列出所有文件;包括首字符为"."的隐含文件;
-N 不处理文件名直接显示,这样在中文环境下就可以显示中文文件名了。

还要注意ls与其它命令搭配使用可以生出很多技巧(最简单的如"ls -l | more")。

为了方便起见,你可以编辑/etc/bashrc或自己家目录(home)下的.bashrc,加入一行:
alias ls="ls --color -F -N" 重新运行一下bash会立即生效,
如果加在/etc/bashrc里则对所有使用bash shell的用户有效。
如果使用的是其它的shell,则去找对应的配置文件。注意不是/etc/aliases文件,
那是sendmail 的别名配置文件。

ls显示的颜色是可以修改的,请参考"Colours with Linux terminals",里面有个shell
脚本可以显示所有的ANSI颜色。你可以去看一下/etc/DIR_COLORS或$HOME/.dir_colors,
要注意两个文件的作用范围不同。

9.复制子目录及子目录下的所有文件
  在用cp时加上-r参数,如"cp -r /mnt/floppy/* /usr/local/"要参考的重要参数是-f -s。

10.文件/目录改名
  简单地用move命令移到新名字下即可。例如"mv /usr/oldname /usr/newname"。

11.怎样删除一个目录下的所有文件和子目录及子目录下的所有文件
  rm -rf /tmp/example

12.怎样显示文件的类型
  用file命令,比如"file /bin/mount","file xxx.gz","file netscape","file initrd.img"等等。
相关的配置文件在/etc/magic或者 /usr/share/magic

13.查找命令文件的路径
  比如你要查找mount命令的具体路径,可以用type mount 、whereis mount,
这个命令还可以找出与这个命令文件相关的文件如manuals page。

14.查找文件
  使用find命令,比如:
find /usr -name XF86* 在/usr目录下(包含子目录)查找名字前四个字母为XF86的文件
find . -name netscape -print 在当前目录下(包含子目录)查找名为netscape的文件
find /home -nouser 在/home目录下查找没有用户属主的文件(用户帐号被删除但有遗留文件)
find /var -newer test 在/var目录下查找比test文件日期更新的文件
  find命令有很多参数,注意用man命令查看。

更快速的查找文件是使用locate,第一次使用locate之前用updatedb来更新文件/目录名数据库。
它把文件/目录信息写到数据库中,以后查找起来就特别的快。updatedb放在crontab中而且缺省
配置是在半夜自动执行。locate存在轻微的安全性问题,因为普通用户可以用它来取得自己不
能访问的目录/文件的部分信息。

15.快速调出历史命令
  可以用上下光标键来调出历史命令,然后用左右光标键移动并可编辑命令行。
详细情况请见下面贴子(有其它想法可跟其贴!)
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=155520

16.关于rpm的小技巧
  1)安装rpm包时显示进度:用-vh参数,如rpm -ivh ipchains-1.3.6-1.i386.rpm,用glint或xrpm则不必。
  2)直接通过ftp来安装rpm包:如rpm -i ftp://ftp.xxx.xxx
  3)校验所有的rpm包,查找丢失的文件:rpm -Va
  4)查找一个文件属于哪个rpm包:例如:rpm -qf /usr/bin/who
  5)列出一个rpm包的描述信息:例如:rpm -qpi mon-0.37j-1.i386.rpm
  6)列出一个rpm包的文件信息:例如:rpm -qpl mon-0.37j-1.i386.rpm

17.使用软盘/光盘等移动介质
  因为Linux下没有A盘D盘的概念。你需要把软盘/光盘设备上的文件系统安装到
Linux目录树上的一个点上,称之为安装点(mount point),通常是一个目录。
安装Linux后会有个缺省的安装点/mnt,在它下面还有/mnt/floppy和/mnt/cdrom。
你可以用mount -t ext2 /dev/fd0 /mnt/floppy <--把Linux文件系统格式的软盘安装上来
单用mount而不跟任何参数可以显示已经安装的文件系统,或者查看/etc/mtab文件.
初学者还经常问到如何格式化磁盘,在Linux里概念有些不同, 称之为制作文件系统
(make filesystem)应该用mkfs命令,由于现在的Linux都使用ext2格式,最好直接使用
mke2fs,比如mke2fs /dev/fd0、 mke2fs /dev/hdb2等等。
如果要对软盘低级格式化,则可以用fdformat,而硬盘在出厂时已经格式化,无须低级
格式化(那是危险的)。检查文件系统则用e2fsck,如e2fsck -av /dev/fd0。

18.列出一个目录占用的空间
  du或du -s或du -k ,du -S | sort -n 可以迅速发现哪个目录是最大的。
用df可以看到已安装的文件系统的空间大小及剩余空间大小。
quota -v查看用户的磁盘空间信息,如果你用quota限制了用户空间大小的话。

19.命令补起(TAB键的妙用)
  很多shell都有这个功能:
1. 只需输入文件或目录名的前几个字符, 然后按TAB键,如无相重的,完整的文件名立即自动
在命令行出现;如有相重的,再按一下TAB键,系统会列出当前目录下所有以这几个字符开头的
名字.例如cd /mnt/cd 自动补起为 cd /mnt/cdrom。
2. 在命令行下,只需输入例如"m",再连续按两次TAB键,系统将列出所有以"m"开头的命令,
(包括自定义的Bshell命令函数),对查找某些记不清楚的命令特有用.
例如输入"ftp",将查到ftp, ftpcount, ftpwho, ftpshut等本不熟悉的命令。

20.让grep搜寻文件及所有子目录下的文件里的内容
例如搜寻ZhXwin下所有C原代码中的"Chinput"(试试取消下行的-q参数):
find /download/ZhXwin -name *.c -exec grep -q -s Chinput {} \; -print
查找所有文件则可以用:find . -type f -exec grep -s chinese {} \; -print 。
如果喜欢图形界面,KDE带的kfind很不错。

21.查看启动时的log信息
  首先去查看/etc/syslog.conf文件,找到对应的文件。
  通常在SlackWare下为/var/adm/messages,在Redhat下为  /var/log/messages。
这些文件可能会很大,要注意备份和删除。

22.产生一个以当日日期为后缀的文件
  file=`date '+%m%d'` | touch todayis.$file
  注意定义file变量中的"`"不是" '",而是左上角数字键1傍边那个(左单引号)。

23.利用Find命令改变所有权
  想要改变当前目录下所有文件的所有权,可以这样:
  find . -exec chown OWNER.[GROUP] {} \; (Solaris)
  find . -exec chown -R OWNER.[GROUP] {} \; (Linux)

24.取消^M字符
  当你FTP一些DOS文件到unix下时,你经常会看见每行文件后面有个讨厌的^M 字符,
有两个简单的方法可以取消它。用"vi"打开此文件,在Command mode下敲入::%s/^V^M//g ,
或者,在UNIX SHELL下敲入: sed 's/^V^M//g' foo > foo.new。

25.KDE是什么?
  KDE是 K桌面环境,是由 Matthias Ettrich 在 1996年启动的一个计划。KDE的目标是
在 Unix操作系统和用户间建立良好的接口。简而言之,KDE将Unix带至桌面!

26.KDE是自由软件?
  是, KDE是遵守GNU的自由软件。在LGPL下所有KDE库都允许开发KDE桌面的程序,
所有KDE应用程序得到GPL许可,KDE使用 Qt C++ 跨平台工具包,有各自的授权。简而言之,
Qt的授权允许你免费使用Qt来开发 X Windows下的软件,只要你的原始代码也自由地被使用。
如果你希望你的原始代码不允许修改,你必须获得Qt的商业授权。你能从Troll Tech web site
找到更多有关Qt信息 和它的授权.如果你怀疑授权,请与Troll Tech web site接触。
  KDE和 Qt是可以通过 CD方式免费获得,运行时无任何费用。

27.在KDE中的K代表什么?
  不表示任何东西。简单地说是 K桌面环境,就象X窗户系统中的X.。

28.KDE能在哪一个平台上工作?
  KDE是所有Unix的桌面环境。大部分KDE开发者使用Linux,KDE平滑地跑在各式各样的系统上。
如果你使用的是Unix变体或不使用GNU开发工具如gcc,你也许要修改源代码。
  可运行KDE的系统有Linux Solaris FreeBSD IRIX HP-UX。

29.KDE是窗口管理程序吗?
  不, KDE不是窗口管理程序。KDE包含一个采用非常先进技术的窗口管理程序称KWM,
KDE是成熟的完整的桌面环境(IDE)。KDE提供完全桌面环境,包括文件管理程序、窗口管理程序、
帮助系统、配置系统、不可数的工具和正在增加的应用程序。

30.KDE是CDE, Windows 95或 MacOS克隆吗?
  不, KDE不是克隆。特别地,KDE不是CDE或Windows克隆。在KDE开发者已经和正在收集所有
存在的桌面环境的最好特性的时候,KDE是真正的,唯一的环境。

31.Linux发布里有 KDE吗?
  是的,主要的Linux分布都已经包含KDE。

32.如何检查正在使用的 KDE的版本?
  看 KDE控制中心。如果没有 KDE的版本号,它肯定是1.0。另一个差别是在面板 'K'字,
在1.0中,它是黑白的3D K,在1.1中,它是在轮子上面的白色K。

33.KDE需要Qt
  对KDE1.0,你需要Qt库1.33或更高的版本。对KDE1.1,你需要Qt库1.42或更高的版本。
但是不要下载Qt 2.0或更高版本。如果你想自己编译 KDE,你也需要头文件。
在 http://www.troll.no/dle有免费资源。你需要的libgr一般包括在大部分发布内。
请务必确认你本地的loopback设备正确设置。

34.Qt是什么?
  Qt是建造使用者接口的C++基类库。它提供大多数widgets、菜单、按钮、sliders等等。
Qt是一个跨平台库,写的代码可在Unix编译,也可在Windows编译。

35.为什么KDE用Qt?
  Qt是一个非常复杂工具包,他提供所有的现代用户接口。Qt由C ++写成,允许使用
object oriented development,…据我们看来没有比它更好的工具可以…。
所有KDE开发者同意如果没有Qt在如此短的时间不可能建造kde。

36.CVS是什么?
  它是Concurrent Versions System的缩写字。它是版本控制系统,以RCS (修订版控制系统)
为基础,但是提供更多机能。它用于维护项目的原始代码。它将保持多个版本的东西,允许远程存
取最近原始代码。

37.怎样快速退出Xwindow?
  Xwindow基本不会出现真正的死机(起码我没见过),如果出现无法运行的情,可以用ctrl+alt+
backspace退出窗口返回到命令行模式。

38.怎样转换虚拟终端?
  在字符模式下用alt+左方向键(或右方向键)可以顺序切换各个虚终端,也可以用alt加F1到6
直接切换到各个虚终端。 在X Window模式下可以用ctrl+alt+F1(F1-F6)切换到各个虚终端,
ctrl+alt+F7切换回窗口。

39.在X Window做文字处理应使用哪个软件?
  在命令行模式下输入kedit命令就可启动字处理软件,其功能类似于Win98的写字板。

三、 有关在linux中执行halt关机命令后出现的一些困惑见下:

Q: halt命令后,系统执行到system halted 时死在那里了,这是什么原因啊?
(or "我的linux是RedHat7.0,每次关机总关不掉主机电源,该怎么办呀?"也可参看下面的)
A: 实际上按照你所说的情况,不算是死机。因为你看到了system haled.....这表明是完全退出了linux操作系统!
就象我们在WIN98里一样(没有支持高级电源管理的情况下,会出现一个"你现在可以安全关闭计算机了"),
而linux默认没有这个提示而已,这时你可以按一下主机上的电源按钮来关机关掉电源!一切OK。
不过你为了达到你所希望的,你可以用以下命令: halt -p 或者poweroff 。
也可以通过修改:/etc/rc.d/init.d/halt中的有关"halt" 为"halt -p" 。
这样你只要用halt就可以在关机时关掉主机上的电源

如果你有其它的想法和不同的观点可以跟以下的贴子:
1,http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=163283
2.http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=138471

四、用软盘启动linux的朋友,在丢了或损坏了软盘时,而Lilo 没在 MBR上,Linux 还能启动吗?
请有这方面需要的朋友看下面这个贴子,或跟其贴!
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=162862

五、有关环境变量的查看、设定、删除
1. 查看环境变量的设定值
语法:setenv 查看所有环境变量的设定值。
语法:echo $NAME 显示指定的环境变量NAME的设定值。
例如:
echo $PRINTER 显示环境变量PRINTER 的设定值。
2. 设定环境变量
语法:setenv NAME word
例如:
setenv PRINTER sp 设定环境变量PRINTER 为sp。
3. 删除环境变量
语法:unsetenv NAME
例如:
unsetenv PRINTER 删除环境变量PRINTER的设定值。

六、linux下是否有病毒的讨论见下:(欢迎谈谈个人看法!)
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=160462

七、关于启动xwindow时如何自行选择gnome或kde?
方法有以下几种:
1.redhat7.1安装时默认启动为命令操作状态,启动时默认为gnome,可是有时候想用kde,
在用户根目录下编辑.xinitrc,加上一条命令startkde即可。
如果还要用gnome的话,只要把.xinitrc删掉就可以了。
2.可以直接修改$HOME/.xinitrc
如果启动gnome
.xinitrc文件内容应该这样写:
exec gnome-session
如果启动KDE
.xinitrc文件内容应该这样写:
exec startkde
3.use command:
switchdesk GNOME
4.在terminal运行:
switchdestop kde
或者
在x-windows下运行:
switchdestop
然后选一个wm

八、怎样使linux启动进入时不直接进入X-WINDOWS界面?
改/etc/inittab文件,将有"id:5:initdefault:"这一行中的,把数字5改成3即可

九、linux 与SVR4 or 4.3BSD有何关系? 请见以下贴子:
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=162987

十、在linux中如何设置系统时间? 参照以下文章:
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=159079

十一、关于swap分区的大小讨论! 参照以下文章:

http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=158857

十二、在没有正常关机的情况下,而后开机时报告文件系统错误,要运行什么fsck?如何使用fsck?
你在shell命令提示符下:打 fsck命令。格式是:fsck /dev/hda? (针对ext2格式的文件也可以用e2fsck)
它还可以带一些参数见下: (详细请用: man fsck)
fsck的参数
-f
即使磁盘看起来无需检查也强制执行。默认情况下,只有当文件系统"肮脏"时才需要进行检查。或者说,只
有当文件系统没有正确卸载(dismount)、或者使用了一定的时间、系统重新启动一定次数后才需要进行检查。
-p
整理文件系统,自动修正所有可以安全地更正且不会导致数据丢失的问题。
-y
对所有问题回答yes。它的效果是:自动修正所有发现的问题,即使那些可能导致数据丢失的问题也要修正。
-b block
指定文件系统备用superblock的位置。在极其罕见的情况下,即当主superblock被损坏而文件系统主要部分仍
完整的情况下,该选项的作用将是非常大的。备用superblock通常位于8193、13685等位置,创建文件系统时
mkfs将输出该信息。

有一点很重要,那就是在检查完文件系统后,如果对该文件系统做了任何纠正,就应该立即重新启动系统(当
然,一般情况下,不能在文件系统被安装时检查它)。例如,如果e2fsck报告对文件系统的错误作了些纠正的话,
就应该立即用shutdown-r命令确保重新启动系统,这使得当e2fsck修改了文件系统后,系统能重新同步读文件
系统的信息。 与fsck相关的内容欢迎参加下面贴子讨论:
http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=newbie&Number=154205


Linux入门》版版主 qiuluhua
2001.10






 
Lhb @ 2004-09-19 10:58

  C++关键字(static/register/atuo/extern/volatile/const)释疑     选择自 njustcxy 的 Blog  
关键字   static register atuo extern volatile const
出处    

下面关于C++的几个关键字是经常和我们打交道的而我们又经常对这些含糊不清的,本文根据自己的学习体会作以总结,以期达到真正理解和活用的目的。

static
l         静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可改变其值。

l         静态变量或静态函数,即只有本文件内的代码才可访问它,它的名字(变量名或函数名)在其它文件中不可见。

l         在函数体内生成的静态变量它的值也只能维持

int max_so_far( int curr )//求至今(本次调用)为止最大值

{

  static int biggest; //该变量保持着每次调用时的最新值,它的有效期等于整个程序的有效期

  if( curr > biggest )

     biggest = curr;

  return biggest;

}

l         在C++类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。

l         类的静态成员变量必须在声明它的文件范围内进行初始化才能使用,private类型的也不例外。如,
              float SavingsAccount::currentRate = 0.00154;
  (注:currentRate是类SavingsAccount的静态成员变量)
register
l         用register声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器中;但对32位编译器不起作用,当global optimizations(全局优化)开的时候,它会做出选择是否放在自己的寄存器中;不过其它与register关键字有关的其它符号都对32位编译器有效。

auto
l         它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。

extern
l         声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义(实现)。在文件内声明一个变量或函数默认为可被外部使用。

l         在C++中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前Microsoft C/C++仅支持”C”转换标记,来支持C编译器链接。使用这种情况有两种形式:

u       extern “C” 声明语句

u       extern “C” { 声明语句块 }

volatile
l         限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:

int volatile nVint;

      这样的声明是不能达到最高效的,因为它们的值随时会改变,系统在需要时会经常读写这个对象的值。       只常用于像中断处理程序之类的异步进程进行内存单元访问。

const
l         const所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。

l         在C++中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在C中,其声明则必须放在源文件(即.C文件)中,在C中const声明一个变量,除了不能改变其值外,它仍是一具变量,如

const int maxarray = 255;

char store_char[maxarray];  //C++中合法,C中不合法

l         const修饰指针时要特别注意。例:

char *const aptr = mybuf;  // 常量指针
*aptr = 'a';       // Legal
aptr = yourbuf;    // Error
const char *bptr = mybuf;  // (指针bptr)指向常量数据
*bptr = 'a';       // Error
bptr = yourbuf;    // Legal
l         const修饰成员函数时不能用于构造和析构函数。