分类存档: 技术文章 - 第3页

RTTI (Run-time type identification) 运行时类型识别

THINKING IN C++(2nd Volume)

8:RTTI (Run-time type identification)

   Two syntaxes for RTTI
   
  <1> typeid()  
   but it’s actually implemented by the compiler.
   这个功能实际上是由编译器实现的,也就是编译的时候就已经决定了。
            ClassA *s;
            cout<<typeid(*s).name() << endl;
           
           if(typeid(me).before(typeid(you))) // …
           
           

           #include <iostream>
using namespace std;

class A
{
   int x;
   virtual func() { cout<<" in Class A;"<<endl; }
};

class B:public A
{
   virtual func() { cout<<" in Class B;"<<endl; }
};

int main()
{
     A *pa;
     B b,*pb;
     pb = &b;
     pa = pb;
     cout<<"Name1:"
          << (typeid(pa).name())<<endl
          <<"Name2:"
          <<typeid(pb).name()<<endl;

     cout<<"pa == pb:"<< (typeid(pa) == typeid(pb))<<endl; // ê?3??aFALSE
       
   if (typeid(*pa).before(typeid(b)))
   {
       cout<<"Class A is NOT before Class B in the collation sequence.";
   }
   else
   {
       cout<<"Class A is before Class B in the collation sequence.";
   }

     return 0;
}
           

           
           程序输出(VC 6.0 注意在Setting里面打开RTTI)
               Name1:class A *
               Name2:class B *
               pa == pb:0
               Class A is before Class B in the collation sequence.

   
   <2>The C++ RTTI typesafe-downcast(保证安全的向下转型)    dynamic_cast.
           Shape* sp = new Circle;
           Circle* cp = dynamic_cast<Circle*>(sp);
           if(cp) cout << "cast successful";
           
   typeid() operator works with built-in  types. 支持内建数据类型
           故如下的语句的结果都是 TRUE
           assert(typeid(47) == typeid(int));
           assert(typeid(0) == typeid(int));
           int i;
           assert(typeid(i) == typeid(int));
           assert(typeid(&i) == typeid(int*));
   
   
       Run-time type identification doesn’t work with void pointers.
       RTTI 不能用于void指针。
       
Using RTTI with templates(RTTI在模板中的应用)
           

//: C08:ConstructorOrder.cpp
// Order of constructor calls
#include <iostream>
#include <typeinfo>

using namespace std;

template<int id> class Announce
{
public:
   Announce()
   {
       cout << typeid(*this).name()<< " constructor " << endl;
   }

   ~Announce()
   {
       cout << typeid(*this).name()<< " destructor " << endl;
   }
};
class X : public Announce<0>
{
   Announce<1> m1;
   Announce<2> m2;
public:
   X() { cout << "X::X()" << endl; }
   ~X() { cout << "X::~X()" << endl; }
};

int main()
{
   X x;
   return 0;
}
           

       输出结果:
class Announce<0> constructor        //基类构造函数
class Announce<1> constructor        //X的成员变量初始化
class Announce<2> constructor        //X的成员变量初始化
X::X()                                                    //X的构造函数
X::~X()

硬盘主引导记录详解(转)

硬盘的数据结构对于一些朋友来说总是很神密!为什么我们删除了的文件用软件能找到?为什么我们格式化了的硬盘数据还能找回来?要回答这一切,你就得对硬盘的数据结构有个清醒的认识。

硬盘上的数据由五大部分组成,它们分别是:MBR区、DBR区,FAT区,DIR区和DATA区。

1.MBR(Main Boot Record)区,即主引导记录区,位于整个硬盘的0磁道0柱面1扇区.

2.DBR(Dos Boot Record)区,操作系统引导记录区。位于硬盘的0磁道1柱面1扇区,是操作系统可以直接访问的第一个扇区.

3.FAT(File Allocation Table文件分配表)区;

4.DIR(Directory)根目录区,记录着根目录下每个文件(目录)的起始单元,文件的属性等;

5.DATA区是真正意义上的数据存储的地方,位于DIR区之后,占据硬盘上的大部分数据空间。

了解了硬盘数据的基本结构,今天我们把重点放在mbr所在的扇区:主引导扇区。主引导扇区包括:mbr,dpt和结束标志。位于硬盘的0磁道0柱面1扇区,用diskman可以读出其中的内容,下面是一次操作的结果:

表一:

0 1 2 3 4 5 6 7 8 9 A B C D E F

00000000 EB48 90D0 BC00 7CFB 5007 501F FCBE 1B7C

00000010 BF1B 0650 57B9 E501 F3A4 CBBE BE07 B104

00000020 382C 7C09 7515 83C6 10E2 F5CD 188B 148B

00000030 EE83 C610 4974 1638 2C74 F6BE 1007 0302

00000040 8000 0080 68B6 7600 0008 FAEA 507C 0000

00000050 31C0 8ED8 8ED0 BC00 20FB A040 7C3C FF74

00000060 0288 C252 BE81 7DE8 3F01 F6C2 8074 5FB4

00000070 41BB AA55 CD13 7256 81FB 55AA 7550 A041

00000080 7C84 C075 0583 E101 7444 B448 BE00 7FC7

00000090 0442 00CD 1372 3766 8B4C 10BE 057C C644

000000A0 FF01 668B 1E44 7CC7 0410 00C7 4402 0100

000000B0 6689 5C08 C744 0600 7066 31C0 8944 0466

000000C0 8944 0CB4 42CD 1372 05BB 0070 EB7D B408

000000D0 CD13 730A F6C2 800F 84E8 00E9 8D00 BE05

000000E0 7CC6 44FF 0066 31C0 88F0 4066 8944 0431

000000F0 D288 CAC1 E202 88E8 88F4 4089 4408 31C0

00000100 88D0 C0E8 0266 8904 66A1 447C 6631 D266

00000110 F734 8854 0A66 31D2 66F7 7404 8854 0B89

00000120 440C 3B44 087D 3C8A 540D C0E2 068A 4C0A

00000130 FEC1 08D1 8A6C 0C5A 8A74 0BBB 0070 8EC3

00000140 31DB B801 02CD 1372 2A8C C38E 0648 7C60

00000150 1EB9 0001 8EDB 31F6 31FF FCF3 A51F 61FF

00000160 2642 7CBE 877D E840 00EB 0EBE 8C7D E838

00000170 00EB 06BE 967D E830 00BE 9B7D E82A 00EB

00000180 FE47 5255 4220 0047 656F 6D00 4861 7264

00000190 2044 6973 6B00 5265 6164 0020 4572 726F

000001A0 7200 BB01 00B4 0ECD 10AC 3C00 75F4 C300

000001B0 0000 0000 0000 0000 4CA6 4CA6 0000 8001

000001C0 0100 0BFE 3FD8 3F00 0000 5A31 3500 0000

000001D0 01D9 0FFE FFFF 9931 3500 04FF FB00 0000

000001E0 0000 0000 0000 0000 0000 0000 0000 0000

000001F0 0000 0000 0000 0000 0000 0000 0000 55AA

这块10.2G(以下显示为9766MB,误差原因不用我解释了吧?)的硬盘共分了四个区:分区结构如下:

主引导扇区中前446字节–偏移地址从0000H-01BDH为mbr区,存放着主引导程序,从上面的显示中,读者可能已经看出,这个硬盘以linux系统的grub为引导程序。

接下来的64字节为硬盘分区表–dpt,偏移地址从01BEH-01FDH,共分为四个分区表项,每个分区表项占16字节,表示一个分区,从这里大家就可以知道为什么硬盘只能分四个主分区了吧?但有时我们需要更多的分区来规划我们的硬盘,为解决这个问题,就把这四个分区表项中的一个定义为扩展分区(与主分区是并列关系),扩展分区中又可以定义逻辑分区(与扩展分区是包含与被包含的关系)。但读者不要以为这些信息都在这一个16字节的分区表项中。事实上是:被定义为扩展分区的这一个分区表项只包含了指向逻辑分区的信息。而逻辑分区的分区表在其它的扇区中存放!

本文重点介绍dpt中的内容,上面已经提到,dpt分为四个分区表项,每个分区表项占16个字节,下面着重讲述这16个字节是怎么分配的。

表三:

第1字节 引导标志,该值为80H表示为可自举分区(活动分区,仅有一个),该值为00H表示其余分区

第2字节 分区起始磁头

第3字节 低6位是分区起始扇区,高2位是分区起始的柱面的头两位

第4字节 分区起始柱面的低8位

第5字节 系统标志

第6字节 分区终止磁头

第7字节 低6位为分区终止扇区,高2位为终止柱面的前2位

第8字节 分区终止柱面的低8位。

第9-12字节 本分区前的扇区数,低位字节在前(注:不是低位在前)

第13-16字节 本分区总的扇区数,低位字节在前

现在根据上面的列表详细解释一下:我们提取出下面四个分区表项:

表四:

分区 | 字节序号

表项 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

1: | 80 01 01 00 0B FE 3F D8 3F 00 00 00 5A 31 35 00

2: | 00 00 01 D9 0F FE FF FF 99 31 35 00 04 FF FB 00

3: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

4: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

由于数据以16进制显示,每个数字占一个字节的四位,所以两个数字占一个字节。

对于第一个分区表项:

第1字节为80,表示活动分区;

第2字节为01,十进制为1,表示起始磁头号;

第3字节为01,二进制为00000001,低6位000001,对应的十进制为1,表示起始扇区;

第4字节为00,二进制为00000000,与第三字节的高2位00组成0000000000,十进制为0,表示起始柱面;

第5字节为0B,为系统标志;

第6字节为FE,十进制为254,表示终止磁头;

第7字节为3F,二进制为00111111,低6位为111111,转换为十进制为63,表示终止扇区;

第8字节为D8,二进制为11011000,与第7字节的高2位00组成0011011000,十进制为216,表示终止柱面;

第9-12字节为3F 00 00 00,按低位字节在前的原则排列为:00 00 00 3F,转换为十进制为63,表示该分区前的扇区数目;

第13-16字节为5A 31 35 00,按低位字节在前的原则排列为:00 35 31 5A,转换为十进制为3486042,表示该分区占用的扇区数目。

我们可以与表2对照,发现两者完全统一!同理,我们还可以分析第2个分区表项,这就交给感兴趣的读者自己完成吧。

在第3和第4个分区表项中,所以数据都为0,表示这两个分区表项没有分配。

最后两个字节–偏移地址从01FEH-01FFH,为结束标志,通常为55 AA,如果改为其它值,则硬盘可能不被引导。

通过以上的讲解,你是不是对硬盘的数据结构又有了更深的认识?对于使用windows和 linux双系统的用户,经常要与mbr打交道,有很多网友问:装了linux和windows双系统,现在又不想使用linux了,于是把linux的分区格式化为fat32回收,但当初装在mbr的引导信息老是去不掉。这里我可以告诉你一个方法,就是用windows98启动盘启动电脑,然后运行 fdisk/mbr命令就可以了,这条命令是重建mbr(前446字节),但并不破坏dpt中的数据,也就是并不破坏硬盘的分区表,可以安全使用。你可以在使用这条命令前后各查看一下主引导扇区,就会发现从447字节开始以后的数据都没有改
。如果你没有diskman这个软件,下面的C程序一样可以帮你搞掂!

以下是程序的源码:

#include <bios.h>

#include <stdio.h>

int main()

{

register int i;

unsigned char buffer[512] = {0};

biosdisk(2, 0×80, 0, 0, 1, 1, buffer);

for (i=0; i<512; i++)

{

if (!(i%8))

{

printf(" ");

if (!(i%16))

{

printf("\n");

printf("%04x:", i);

}

}

printf("%02x ", buffer);

}

}

在turboc2.0中可编译通过。运行biosdisk()函数,你还可进一步编写备份mbr,恢复mbr的程序或把mbr清0的程序,是不是很想试试。

Install mysql on Debian Linux(Not finished yet)

Installing Apache, MySQL, and PHP on Linux

                                                                         

Get the sourceballs -

 

The first thing you need to  do is obtain the sourceballs for each package, we will be compiling each package  from scratch here, and, while there are also binary packages available for some  distributions, I find your end results are usually better when building each  package for your machine. Make sure you get the source files.


Here are the links and the  package versions available at the time this tutorial was written


Apache
URL : http://httpd.apache.org/download.cgi
Current Version – 2.0.48


MySQL
URL : http://www.mysql.com/downloads/mysql-4.0.html
Current Version – 4.0.16


PHP
URL : http://www.php.net/downloads.php
Current Version – 4.3.4


Ok, so you've got the files  now what ?, well now the fun begins..


Installation –


The first thing we need to  do is extract the sourceballs so we can work with the files included in them.  Beginning now we will be working as root, so open a terminal window, change to  the directory in which you saved your downloaded files and become root by  issuing the su command, enter the root password and you should be good to  go.


To extract the sourceballs  type the following commands;


#tar -zxf  httpd-2.0.48.tar.gz (enter)


#tar -zxf  mysql-4.0.16.tar.gz (enter)


#tar -zxf  php-4.3.4.tar.gz (enter)


The commands above will  extract the sourceballs into their own separate directories. Now lets move on to  compiling the source into usable programs. We'll start  with Apache.


Compiling Apache –


Change into the directory  created when you untarred the sourceball as follows;


#cd httpd-2.0.48 (enter)


Follow this command by  typing;


#./configure –prefix=/usr/local/apache2  –enable-mods-shared=most (enter)


This tells Apache to  install in the /usr/local/apache2 directory, and to build most of the  available loadable modules. There are a ton of options with Apache, but these  should work for the most part. Once the configure is done and the system returns  the prompt to you, issue the following command;


#make


This will take a few  minutes, once the prompt comes back again issue the following command;


#make install


Wait for a few minutes and  viola !, Apache is installed with the exception of a few minor changes we still  need to make. They are as follows..


Issue the following  command;


#vi /usr/local/apache2/conf/httpd.conf


Check to make sure the  following line is present in the file at the bottom of the LoadModule list, if  it is not there add it;


LoadModule php4_module  modules/libphp4.so


Find the DirectoryIndex  line and edit it so it looks like the following;


DirectoryIndex  index.html index.html.var index.php


Find the AddType  application section and add the following line;


AddType application/x-httpd-php  .php


Thats it, save the file and  we are done with Apache. Now, on to MySQL !


Compiling MySQL -


Change into the MySQL  source directory as follows;


#cd mysql-4.0.16 (enter)


Follow this command by  typing;


#./configure –prefix=/usr/local/mysql  –localstatedir=/usr/local/mysql/data –disable-maintainer-mode –with-mysqld-user=mysql  –enable-large-files-without-debug (enter)


Sit back and wait for a  while while configure does its thing, once the system returns the prompt to you  issue the following command;


#make (enter)


Unless you have a very fast  machine this will take some time, so spend time with your family, grab a beer,  go for a walk, or whatever you're into. When you get back, assuming the system  has returned the prompt to you issue the following command;


#make install (enter)


Cool !, MySQL is installed,  there are only a couple things left to do to get it working, first we need to  create a group for MySQL as follows;


#/usr/sbin/groupadd  mysql (enter)


Then we create a user  called mysql which belongs to the mysql group;


#/usr/sbin/useradd -g  mysql mysql (enter)


Now we install the database  files as follows;


#./scripts/mysql_install_db  (enter)


Then we make a couple minor  ownership changes;


# chown -R root:mysql /usr/local/mysql  (enter)


<
p># chown -R mysql:mysql /usr/local/mysql/data  (enter)


Last but not least, we use  vi to add a line the ld.so.conf file as follows;


#vi /etc/ld.so.conf


And we add the following  line;


/usr/local/mysql/lib/mysql


Thats it, MySQL is  installed, you can run it by issuing the following command;


#/usr/local/mysql/bin/mysqld_safe  –user=mysql &


And as long as we're here  we might as well set a root password for MySQL as follows;


#/usr/local/mysql/bin/mysqladmin  -u root password new_password


Where new_password is the  password you want to use.


Ok, so far so good, on to  PHP !


Compiling PHP -


Change into the PHP source  directory as follows;


#cd php-4.3.4 (enter)


Follow this command by  typing;


#./configure –prefix=/usr/local/php  –with-apxs2=/usr/local/apache2/bin/apxs –with-mysql=/usr/local/mysql (enter)


Once the prompt comes back  to you issue the following command;


#make (enter)


Hang out for awhile, and  then yep, you guessed it, once you have the prompt back;


#make install (enter)


Once the install finishes  and you have the prompt back issue the following command;


#cp php.ini-recommended  /usr/local/php/lib/php.ini (enter)


Then edit that file;


#vi /usr/local/php/lib/php.ini  (enter)


And change the following;


Find the doc_root  section and enter the correct path for the directory which serves your web  content, such as;


doc_root= "/usr/local/apache2/htdocs/"


(this is default for  apache2)


Then find the file_uploads  section and change it to reflect the following;


file_uploads=Off


(for security reasons)


Thats if for PHP, now lets  see if it all works..


Testing –


Assuming your MySQL process  is still running from earlier, lets start Apache by issuing the following  command;


#/usr/local/apache2/bin/apachectl  start (enter)


This starts the Apache web  server, now change into the following directory;


#cd /usr/local/apache2/htdocs  (enter)


And using vi create a file  called test.php;

 

#vi test.php

 

Add the following line to  the file;


<?php phpinfo(); ?>


Save the file, then fire up  your browser and point it to localhost/test.php. You should see a listing  of all kinds of cool info about Apache, PHP, etc. If you do then your set !, if  you don't, then take a look at your logs for Apache and MySql, and remember Google  is your friend. But hopefully you do, and now you have a fully functioning  setup.


Ok, one last step and we'll  be done, you have everything running now, but you had to start Apache and MySql  manually, that's something you don't want to have to remember to do everytime  you reboot your machine, so lets fix it.

 


Articles from the official website:

 Causes of Access denied Errors

        If you encounter problems when you try to connect to the MySQL         server, the following items describe some courses of action you         can take to correct the problem.      

  •             Make sure that the server is running. If it is not running,             you cannot connect to it. For example, if you attempt to             connect to the server and see a message such as one of those             following, one cause might be that the server is not             running:          

    shell> mysqlERROR 2003: Can't connect to MySQL server on 'host_name' (111)shell> mysqlERROR 2002: Can't connect to local MySQL server through socket'/tmp/mysql.sock' (111)

                It might also be that the server is running, but you are             trying to connect using a TCP/IP port, named pipe, or Unix             socket file different from the one on which the server is             listening. To correct this when you invoke a client program,             specify a –port option to indicate the             proper port number, or a –socket option to             indicate the proper named pipe or Unix socket file. To find             out where the socket file is, you can use this command:          

    shell> netstat -ln | grep mysql 
  •             The grant tables must be properly set up so that the server             can use them for access control. For some distribution types             (such as binary distributions on Windows, or RPM             distributions on Linux), the installation process             initializes the mysql database containing             the grant tables. For distr
    ibutions that do not do this, you             must initialize the grant tables manually by running the             mysql_install_db script. For details, see             Section 2.4.16.2, “Unix Post-Installation Procedures”.          

                One way to determine whether you need to initialize the             grant tables is to look for a mysql             directory under the data directory. (The data directory             normally is named data or             var and is located under your MySQL             installation directory.) Make sure that you have a file             named user.MYD in the             mysql database directory. If you do             not, execute the mysql_install_db script.             After running this script and starting the server, test the             initial privileges by executing this command:          

    shell> mysql -u root test 

                The server should let you connect without error.          

  •             After a fresh installation, you should connect to the server             and set up your users and their access permissions:          

    shell> mysql -u root mysql 

可是偶的mysql 还是不能正常工作,郁闷阿

# /usr/local/mysql/bin/mysqladmin -u root test
/usr/local/mysql/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: NO)'

初识WordPress

From WordPress 中文文档

关于 WordPress

"WordPress was born out of a desire for an elegant, well-architectured personal publishing system built on PHP and MySQL and licensed under the GPL. It is the official successor of b2/cafelog. WordPress is fresh software, but its roots and development go back to 2001. It is a mature and stable product. We hope by focusing on web standards and user experience we can create a tool different from anything else out there."

WordPress功能      

WordPress可以

  1. 进行文章发布、分类、归档。  
  2. 支持文章、评论、分类等多种形式的RSS输出。  
  3. 提供链接的添加、归类功能。  
  4. 支持评论的管理,防垃圾功能。  
  5. 支持对风格(CSS)和程序本身(PHP)的直接编辑、修改。  
  6. 在Blog系统外,方便的添加所需页面。  
  7. 通过对各种参数进行设置,使你的Blog更具个性化。  
  8. 生成静态html页面(需要mod_rewrite支持)。  
  9. 通过选择不同主题,方便地改变页面的显示效果。  
  10. 通过添加插件,可提供多种特殊的功能。  
  11. 支持Trackback和pingback。  
  12. 支持针对某些其它blog软件、平台的导入功能。  
  13. 支持多用户。

WordPress的主要优势在于:

  1. 安装最简单。  
  2. Web标准支持非常好。  
  3. 使用比较简单。  
  4. 主题与插件丰富。因此可以方便地打造自己喜欢的Blog显示效果和功能,让它在简单的同时,变得更加美观、强大。  
  5. 功能设置比较合适、合理,不像有些软件那样多而无用。  
  6. 代码修改比较方便、容易。  

相关链接:
http://wordpress.org/download/
http://codex.wordpress.org.cn/

Canonical URL by SEO No Duplicate WordPress Plugin