• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            寶杉的博客

            UNIX/LINUX;ACE;SNMP;C++
            posts - 33, comments - 23, trackbacks - 0, articles - 0

             

             錯誤

            #include   <iostream.h>
            #include   <string.h>

            ……

            string   st("test   string");  

            ……

            error   C2065:   'string'   :   undeclared   identifier  

            解釋

            #include   <string>  

            using   namespace   std;  

            因為在   using   namespace   std;   情況下, 

            #include   <string>     是使用   C++     string   類庫; 

            #include   <cstring>     是使用   C   的string   操作庫函數   ...  

            細節 加不加“.h”

            #include <iostream.h>

            #include <string>

            using       namespace      std;

            沒有錯!!

            #include <iostream.h>

            #include <string.h>

            using       namespace      std;

            編譯有錯!!

            解釋

              “string.h“這個頭文件是“舊式c頭文件”,而這個文件中沒有定義string類(這點應該不奇怪,c語言中哪有什么類啊),這個頭文件里面是有關“舊式char-based字符串”的操作函數,注意都是操作char*字符串的“函數”,所以你引用這個頭文件,編譯器肯定找不到“string”了。  
              “string”這個頭文件(沒有擴展名)是C++標準化之后的C++頭文件,里面才有string類的相關定義(其實,string并不是類,是一個typedef,但是使用的時候不用去管他),而C++標準頭文件中的東西都放在namespace   std中了,所以使用的時候要“using   namespace   std”。  
              附:建議樓主不要用"iostream.h",改成“iostream”吧,因為標準已經明確規定不在支持"iostream.h"這種頭文件了。

            標準寫法

            #include <iostream>

            #include <string>

            using       namespace      std;

             

            F: 為什么using   namespace   std;  
                   要寫在include后面?

            Q: 因為include的文件包含名字域std  
            如果你把using   namespace   std寫在前面,編譯器就看不到std這個名字

            posted @ 2007-08-03 13:01 寶杉 閱讀(416) | 評論 (0)編輯 收藏

             

            引用即別名,數組不能引用。

            引用提高效率,又不在函數中改變。參考:file:///F:/fragments/documents/深入探討C++中的引用%20-%20KiRa的專欄%20-%20CSDNBlog.mht

             

            常引用

            常引用聲明方式:const 類型標識符 &引用名 = 目標變量名;

            const類型 和 & 是分不開的,引用一般定義成const。

             

            引用作為返回值

            要以引用返回函數值,則函數定義時要按以下格式:

            類型標識符 &函數名(形參列表及類型說明)
            {

            函數體

            }

            說明:

              (1)以引用返回函數值,定義函數時需要在函數名前加&

              (2)用引用返回一個函數值的最大好處是,在內存中不產生被返回值的副本。

            例子:Diary files\C++exams\rtn_ref

             

            引用作為返回值,必須遵守以下規則:

            (1)不能返回局部變量的引用。這條可以參照Effective C++[1]的Item 31。主要原因是局部變量會在函數返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進入未知狀態。

            (2)不能返回函數內部new分配的內存的引用。這條可以參照Effective C++[1]的Item 31。雖然不存在局部變量的被動銷毀問題,可對于這種情況(返回函數內部new分配內存的引用),又面臨其它尷尬局面。例如,被函數返回的引用只是作為一個臨時變量出現,而沒有被賦予一個實際的變量,那么這個引用所指向的空間(由new分配)就無法釋放,造成memory leak。

            (3)可以返回類成員的引用,但最好是const。這條原則可以參照Effective C++[1]的Item 30。主要原因是當對象的屬性是與某種業務規則(business rule)相關聯的時候,其賦值常常與某些其它屬性或者對象的狀態有關,因此有必要將賦值操作封裝在一個業務規則當中。如果其它對象可以獲得該屬性的非常量引用(或指針),那么對該屬性的單純賦值就會破壞業務規則的完整性。

            (4)引用與一些操作符的重載:

              流操作符<<和>>,這兩個操作符常常希望被連續使用,例如:cout << "hello" << endl; 因此這兩個操作符的返回值應該是一個仍然支持這兩個操作符的流引用。可選的其它方案包括:返回一個流對象和返回一個流對象指針。但是對于返回一個流對象,程序必須重新(拷貝)構造一個新的流對象,也就是說,連續的兩個<<操作符實際上是針對不同對象的!這無法讓人接受。對于返回一個流指針則不能連續使用<<操作符。因此,返回一個流對象引用是惟一選擇。這個唯一選擇很關鍵,它說明了引用的重要性以及無可替代性,也許這就是C++語言中引入引用這個概念的原因吧。 賦值操作符=。這個操作符象流操作符一樣,是可以連續使用的,例如:x = j = 10;或者(x=10)=100;賦值操作符的返回值必須是一個左值,以便可以被繼續賦值。因此引用成了這個操作符的惟一返回值選擇。

            posted @ 2007-08-03 13:00 寶杉 閱讀(194) | 評論 (0)編輯 收藏

             

            在Visual C++中,可以在函數類型前加_cdecl,_stdcall或者_pascal來表示其調用規范(默認為_cdecl)

            // 被調用函數是以int為參數,以int為返回值
            __stdcall int callee(int);

            // 調用函數以函數指針為參數
            void caller( __cdecl int(*ptr)(int));

            // 在p中企圖存儲被調用函數地址的非法操作
            __cdecl int(*p)(int) = callee; // 出錯

            指針p和callee()的類型不兼容,因為它們有不同的調用規范。因此不能將被調用者的地址賦值給指針p,盡管兩者有相同的返回值和參數列。 

            posted @ 2007-08-03 12:59 寶杉 閱讀(512) | 評論 (0)編輯 收藏

             

            聲明:

            先定義函數,void print(string str);

            聲明一個函數指針,void ( *p )( string ) = NULL;

            指向copy函數,p = & print; 或 p = print;

            調用指針函數,p( “hello” );

             

            可以把多個函數放在一個指針數組里,然后通過數組對應指針方便調用函數。

            例子:Diary files\C++exams\pointer_func

             

            動態綁定一個函數

            void caller(void(*ptr)())

            {

            ptr();             /* 調用ptr指向的函數 */

            }

            void func();

            int main()

            {

            p = func;

            caller(p); /* 傳遞函數地址到調用者 */

            }

            如果賦了不同的值給p(不同函數地址),那么調用者將調用不同地址的函數。賦值可以發生在運行時,這樣使你能實現動態綁定。

            posted @ 2007-08-03 12:58 寶杉 閱讀(141) | 評論 (0)編輯 收藏

            靜態聯編:運行之前就完成的聯編,系統在編譯時就決定如何完成某個動作。
            動態聯編:程序運行之后才完成的聯編,系統在運行時動態實現某一動作。
            靜態多態性:函數重載;運算符重載;
            動態多態性:繼承;虛函數;
            函數重載
            1 參數有差別。
            2 參數相同,屬不同類。
            一個重載的例子:Diary files\C++exams\func_reload
             
            名字壓延:是編譯器根據函數重載的不同類型,在編譯時改變函數名字,而達到區分的目的。

            posted @ 2007-08-03 12:57 寶杉 閱讀(144) | 評論 (0)編輯 收藏

            友元函數一般在類中聲明,如果一個友元需要訪問多個類的對象,那么每個類都要聲明一次友元函數。

            還要注意:友元函數的入口包括多個類,那這些類都要在友元函數之前聲明。

            如例子:Diary files\C++exams\frnd_vst2_func

            如果是類person的兩個繼承他的子類boy和girl,那么友元函數如何聲明和定義。

            Diary files\C++exams\frnd_member

            這需要注意的地方有:

            基類的數據成員共有;構造函數;構造函數初始化表;類的聲明先于友元函數,提高了重用性;

            基類的數據成員必須共有,因為構造函數會訪問到它們,子類的構造函數也會引用基類的構造函數,如果是私有的會是的子類構造函數不能直接訪問基類的私有成員,要通過基類的成員函數來訪問。

            子類:public基類

             

            還有寫細節問題:

            頭文件;char *a的聲明和使用;分配char*數據;

            例如:

            char *name;

            name = new char[ strlen( s ) + 1 ];

             

            友元函數的聲明時的入口參數可以只寫類型,不寫參數名。

            例如:

            class boy

            {

                   ……

                   void disp( gril & );

            }

            注意聲明時的入口參數可省略,但要寫&。

            定義時,寫成

            void disp( gril &x ){      ……       }

            posted @ 2007-08-03 12:55 寶杉 閱讀(1014) | 評論 (0)編輯 收藏

             

            聲明:           類    對象;     類       *指針;

                               int  i;           <class>      *this;

             

            this指針是一個隱含指針,是成員函數所屬對象的指針。

            每個成員函數都有一個this指針,this指針指向該函數所屬類的對象。

             

            使用格式:this -> 成員變量

             

            不同的對象調用同一個成員函數,C++會根據成員函數的this指針指向哪一個對象,來調用該對象的成員變量。

             

            this指針如何得到對象名?

            例如:一個類class me的初始化函數:

            void init(char ma, int mb)

            { a = ma; b = mb; }

            編譯時,被編譯器轉化為:

                   void init(me *this, char ma, int mb)     //多了一個this指針的參數,指向me類的obj

                  { this -> a = ma, this -> b = mb; }

            posted @ 2007-08-03 12:53 寶杉 閱讀(282) | 評論 (0)編輯 收藏

             

               對于只做輸入用的指針參數,最好用const,這樣避免指針參數被修改。

               比如:對于上面的StringCopy的例子,寫成

               void StringCopy (char *strDestination, const char *strSource);         //比較安全。

               但是如果輸入參數以值傳遞的形式傳遞對象,則改為使用const &最好,因為省去了臨時對象的構造和解析的過程,提高效率和安全性。

             

               int printf(……);這個函數的參數不確定,沒有嚴格的類型檢查,所以最好不用。

            posted @ 2007-08-03 12:52 寶杉 閱讀(354) | 評論 (1)編輯 收藏

             

            1 介紹

            此文描述了組成ACE框架的Reactor模式的設計和執行。Reactor負責處理由一個或多個client并發的傳遞給一個應用程序的服務請求。應用程序的每個服務由一個分離的event handler(事件句柄)執行,event handler包括一個或多個進程的服務器特殊請求的方法。

                   此文描述的Reactor模式的執行,event handler分發是由ACE_Reactor實現的。ACE_Reactor結合I/O事件的分離器,以及其他類型的時間,比如timers和signals。ACE_Reactor的核心實現是基于同步事件分離,比如select或者WaitForMultipleObjects。當分離器指示指定的事件發生了,ACE_Reactor會自動分發預先注冊的事件句柄的方法。注冊的event handler方法會完成應用程序對應請求事件的服務。

                   本文組織如下:第二章描述ACE_Reactor框架主要特性;第三章大致介紹ACE_Reactor實現的OO(面向對象)設計;第四章舉了服務器端實現的例子,用以證明ACE_Reactor怎樣簡化并發的,基于事件的網絡應用程序的發展;第五章描述當使用ACE_Reactor開發基于事件的應用程序的設計規則;第六章是結束語。

            2 ACE_Reactor的特性

            ACE_Reactor提供OO的事件分離機制和消息分發框架,它簡化基于事件的應用程序的開發。以下特性是:

            OO的事件分離和消息分發接口:

            使用ACE_Reactor的應用程序不直接調用底層OS(操作系統)的事件分離API函數。比如select或WaitForMultipleObjects。他們繼承ACE Event Handler基類并創建了具體的event handlers。這個類用特定的虛擬函數處理不同類型的事件,比如I/O事件,timer事件,signals(信號量機制),和同步事件。

            應用程序用Reactor框架創建具體的event handler,并注冊他們。特性1顯示了ACE Reactor.的關鍵組件。這個特性描述執行日子服務的事件句柄,這個在第四章講述。

            posted @ 2007-08-03 12:42 寶杉 閱讀(1591) | 評論 (0)編輯 收藏

                  ACE中的流包裝提供面向連接的通信。流數據傳輸包裝類包括ACE_SOCK_Stream和ACE_LSOCK_Stream,它們分別包裝TCP/IP和UNIX域socket協議數據傳輸功能。連接建立類包括針對TCP/IP的ACE_SOCK_Connector和ACE_SOCK_Acceptor,以及針對UNIX域socket的ACE_LSOCK_Connector和ACE_LSOCK_Acceptor。
                  Acceptor類用于被動地接受連接(使用BSD accept()調用),而Connector類用于主動地建立連接(使用BSD connect()調用)。
                  下面的例子演示接收器和連接器是怎樣用于建立連接的。該連接隨后將用于使用流數據傳輸類來傳輸數據。

            server端代碼:
            // 環境VC6.0+ACE5.4.2
            // proj:ACE stream server
            // date:07-7-24
            // robin
            //

            #include "stdafx.h"

            #include "ace/Log_Msg.h"
            #include "ace/Time_Value.h"
            #include "ace/OS.h"


            #include "ace/SOCK_Acceptor.h"
            #include "ace/SOCK_Stream.h"

            #define SIZE_DATA 18
            #define SIZE_BUF 1024
            #define NO_ITERATIONS 5

            class Server
            {
            public:
             Server (int port) : server_addr_(port),peer_acceptor_(server_addr_)
             {
              data_buf_ = new char[SIZE_BUF];
             }

             //Handle the connection once it has been established. Here the
             //connection is handled by reading SIZE_DATA amount of data from the
             //remote and then closing the connection stream down.

             int handle_connection()
             {
              // Read data from client
              for(int i=0;i<NO_ITERATIONS;i++)
              {
               int byte_count=0;
               if( (byte_count = new_stream_.recv_n(data_buf_, SIZE_DATA, 0) ) == -1 )
                ACE_ERROR ((LM_ERROR, "%p\n", "Error in recv"));
               else
               {
                data_buf_[byte_count]=0;
                ACE_DEBUG((LM_DEBUG,"Server received %s \n",data_buf_));
               }
              }

              // Close new endpoint
              if (new_stream_.close () == -1)
               ACE_ERROR ((LM_ERROR, "%p\n", "close"));
              return 0;
             }


             //Use the acceptor component peer_acceptor_ to accept the connection
             //into the underlying stream new_stream_. After the connection has been
             //established call the handle_connection() method.
             
             int accept_connections ()
             {
              if (peer_acceptor_.get_local_addr (server_addr_) == -1)
               ACE_ERROR_RETURN ((LM_ERROR,"%p\n","Error in get_local_addr"),1);
              ACE_DEBUG ((LM_DEBUG,"Starting server at port %d\n",
               server_addr_.get_port_number ()));
              
              // Performs the iterative server activities.

              while(1)
              {
               ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
               if (peer_acceptor_.accept(new_stream_, &client_addr_, &timeout)== -1)
               {
                ACE_ERROR ((LM_ERROR, "%p\n", "accept"));
                continue;
               }
               else
               {
                ACE_DEBUG((LM_DEBUG,
                 "Connection established with remote %s:%d\n",
                 client_addr_.get_host_name(),client_addr_.get_port_number()));

                //Handle the connection
                handle_connection();
               }
              }
             }

            private:
             char *data_buf_;
             ACE_INET_Addr server_addr_;
             ACE_INET_Addr client_addr_;
             ACE_SOCK_Acceptor peer_acceptor_;
             ACE_SOCK_Stream new_stream_;
            };


            int main (int argc, char *argv[])
            {
             if(argc<2)
             {
              ACE_ERROR((LM_ERROR,"Usage %s <port_num>", argv[0]));
              ACE_OS::exit(1);
             }

            // char *ip;
            // ip = new char[strlen("192.168.1.160")];
            // Server server(ACE_OS::atoi(ip));  //argv[1])

             Server server(ACE_OS::atoi(argv[1]));
             server.accept_connections();
             return 0;
            }

            client端:
            // proj:ACE stream client
            // client
            // date:7-24
            // robin

            #include "stdafx.h"

            //******additional*******//
            #include "ace/Log_Msg.h"  //ACE_ERROR ACE_DEBUG
            #include "ace/Time_Value.h"  // ACE_Time_Value
            #include "ace/OS.h"    // ACE_OS::atoi exit
            //******additional*******//

            #include "ace/SOCK_Connector.h"
            #include "ace/INET_Addr.h"

            #define SIZE_BUF 128
            #define NO_ITERATIONS 5


            class Client
            {
            public:
             Client(char *hostname, int port):remote_addr_(port,hostname)
             {
              data_buf_="Hello from Client";
             }

             //Uses a connector component `connector_’ to connect to a
             //remote machine and pass the connection into a stream
             //component client_stream_
             int connect_to_server()
             {
              // Initiate blocking connection with server.
              ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting connect to %s:%d\n",
               remote_addr_.get_host_name(),remote_addr_.get_port_number()));
              if (connector_.connect (client_stream_, remote_addr_) == -1)
               ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","connection failed"),-1);
              else
               ACE_DEBUG ((LM_DEBUG,"(%P|%t) connected to %s\n",
               remote_addr_.get_host_name ()));
              return 0;
             }


             //Uses a stream component to send data to the remote host.
             int send_to_server()
             {
              // Send data to server
              for(int i=0;i<NO_ITERATIONS; i++)
              {
               if (client_stream_.send_n (data_buf_,
                ACE_OS::strlen(data_buf_)+1, 0) == -1)
               {
                ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","send_n"),0);
                break;
               }
              }
              //Close down the connection
              close();
             }

             //Close down the connection properly.
             int close()
             {
              if (client_stream_.close () == -1)
               ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","close"),-1);
              else
               return 0;
             }
            private:
             ACE_SOCK_Stream client_stream_;
             ACE_INET_Addr remote_addr_;
             ACE_SOCK_Connector connector_;
             char *data_buf_;
            };


            int main(int argc, char* argv[])
            {
             if(argc<3)
             {
              ACE_DEBUG((LM_DEBUG,"Usage %s <hostname> <port_number>\n", argv[0]));
              ACE_OS::exit(1);
             }

             Client client(argv[1],ACE_OS::atoi(argv[2]));
             client.connect_to_server();
             client.send_to_server();
             return 0;
            }


            運行結果:
            cmd里到exe目錄下,先啟動服務端server.exe 192.168.1.160
            如圖1:

            正在輪詢等待。

            再到client服務端,同樣的方法
            運行命令行參數格式 client.exe 192.168.1.160 192
             解析:ACE_DEBUG((LM_DEBUG,"Usage %s <hostname> <port_number>\n", argv[0]));
                     命令行參數為 <hostname><port> = <192.168.1.160><192>
                     端口是由圖1的第二行顯示,不是自己設定的。
            如圖2:

            只是照搬書上的例子,后面打算自己分析一下。

            posted @ 2007-07-25 10:57 寶杉 閱讀(1424) | 評論 (2)編輯 收藏

            僅列出標題
            共4頁: 1 2 3 4 
            性做久久久久久久久老女人| 区久久AAA片69亚洲| 国内精品人妻无码久久久影院 | 亚洲国产日韩欧美久久| 久久av高潮av无码av喷吹| 久久精品18| 国产激情久久久久久熟女老人| 久久精品99久久香蕉国产色戒| 国产高清国内精品福利99久久| 看全色黄大色大片免费久久久| 午夜天堂精品久久久久| 国内精品久久人妻互换| 国产一区二区精品久久凹凸| 91麻豆国产精品91久久久| 97久久香蕉国产线看观看| 久久精品国产一区二区| 久久久久人妻一区精品色 | 亚洲乱码精品久久久久..| 久久国产乱子精品免费女| 香蕉aa三级久久毛片| 久久午夜无码鲁丝片| 四虎久久影院| 97久久精品无码一区二区| 亚洲精品乱码久久久久久按摩| 久久精品国产清自在天天线| 国产午夜免费高清久久影院| 久久午夜夜伦鲁鲁片免费无码影视 | 国产激情久久久久影院小草| 亚洲欧美伊人久久综合一区二区| 2020最新久久久视精品爱| 久久精品一本到99热免费| 欧美国产成人久久精品| 亚洲精品成人网久久久久久| 国产激情久久久久影院老熟女免费| 久久综合狠狠综合久久| A级毛片无码久久精品免费 | 久久久久se色偷偷亚洲精品av| 国产精品99久久久久久董美香| 精品久久久久久国产91| 狠狠色丁香久久婷婷综合五月 | 国产高潮国产高潮久久久|