friend 不會受到 private protected public 的影響!!
friend有可能是一個namespace的函式.也可能是class member function 也可能是朋友類別 .
當 class test{
};
架構定義下之後並沒有配制到記憶體內,只有當 test aa;時才會,這和JAVA小小的不同
JAVA要new過之後才算數.
星期四, 7月 27, 2006
星期三, 7月 19, 2006
MFC 讀一張bmp and 秀出來
如果要用DIB就要傳一堆的參數給DIB的section
比如說加上一些有的沒的資料結構
struct {
BITMAPINFOHEADER info;
DWORD Bitfield[3];
}Header;
可以存一些BMP裡面的資訊,比如說,size,
void CChildView::OnPaint()
{
CPaintDC dc(this);
HDC memDC;
memDC=::GetDC(0);
HDC dd;
dd=::CreateCompatibleDC(memDC);
hbitmap=(HBITMAP)::LoadImage(::GetModuleHandle(0), _T("acropolis.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
holdbitmap=::SelectObject(dd,hbitmap);
// Attach(memDC);
// memDC.CreateCompatibleDC(dc);
BitBlt(dc,0,0,1024,600,dd,0,0,SRCCOPY); //BitBLT是秀圖用的funtion 第一個參數是準備要秀圖的dc,後面的dd是存好圖的的dd,第一個x,y是基準座標,然後是大小,後面的x,y是dd裡面的坐標.最後要加上SRCCOPY
比如說加上一些有的沒的資料結構
struct {
BITMAPINFOHEADER info;
DWORD Bitfield[3];
}Header;
可以存一些BMP裡面的資訊,比如說,size,
void CChildView::OnPaint()
{
CPaintDC dc(this);
HDC memDC;
memDC=::GetDC(0);
HDC dd;
dd=::CreateCompatibleDC(memDC);
hbitmap=(HBITMAP)::LoadImage(::GetModuleHandle(0), _T("acropolis.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
holdbitmap=::SelectObject(dd,hbitmap);
// Attach(memDC);
// memDC.CreateCompatibleDC(dc);
BitBlt(dc,0,0,1024,600,dd,0,0,SRCCOPY); //BitBLT是秀圖用的funtion 第一個參數是準備要秀圖的dc,後面的dd是存好圖的的dd,第一個x,y是基準座標,然後是大小,後面的x,y是dd裡面的坐標.最後要加上SRCCOPY
星期一, 7月 17, 2006
星期四, 7月 13, 2006
Makefile 小試身手
main.cpp
#include <iostream>
using namespace std
int main(void)
{
cout << "Can You Feel My World?" ;
return 0;
}
----------------------------------------------
all:main.cpp
<tab> g++ main.cpp -g -o run
注意一點 <tab>要按tab 按了g++那行變紅色才ok不然不會過的呦
等瞭解多一點在寫個解釋的文
星期日, 7月 09, 2006
SIP Solution 中四種穿透 NAT 的方式
一般而言,四種穿透 NAT 方式的 TURN / STUN / UPnP / VPN 皆為 SIP message 由 Proxy Server 處理,而 RTP 由外部伺服器處理,這種解決方案需 2 台 Server 。
Proxy Server
CPE 在真實 ip 下,相互知道彼此的 ip 位址及通訊埠 (port) ,能夠順利接通。但 在 NAT 下,相互不知道 IP 位址及通訊埠,須藉由外部伺服器才能夠順利接通。這就是 Proxy Server 的最主要功能。
Proxy Server
CPE 在真實 ip 下,相互知道彼此的 ip 位址及通訊埠 (port) ,能夠順利接通。但 在 NAT 下,相互不知道 IP 位址及通訊埠,須藉由外部伺服器才能夠順利接通。這就是 Proxy Server 的最主要功能。
星期四, 7月 06, 2006
Universal Plug and Play
肥軟MSDN
MSDN
Universal Plug and Play technology is an architecture for pervasive peer-to-peer network connectivity of PCs of all form factors, intelligent appliances, and wireless devices. UPnP technology is a distributed, open networking architecture that leverages TCP/IP and the Web to enable seamless proximity networking in addition to control and data transfer among networked devices in the home, office, and everywhere in between.
萬用隨插即用?我想改叫成全能的插和玩,或許有趣點.
MSDN
Universal Plug and Play technology is an architecture for pervasive peer-to-peer network connectivity of PCs of all form factors, intelligent appliances, and wireless devices. UPnP technology is a distributed, open networking architecture that leverages TCP/IP and the Web to enable seamless proximity networking in addition to control and data transfer among networked devices in the home, office, and everywhere in between.
萬用隨插即用?我想改叫成全能的插和玩,或許有趣點.
socket of UDP with C
剛剛寫的是TCP而UDP?
UDP有小小的不同在
socket(AF_INET,SOCK_DRGAM,0);
小小的變動
UDP的程式裡面少了list和accept ,TCP因為3方交握,所以龜毛的要確認來方.UDP就不用了,所以資料傳輸容易miss
//--------------------------------------------------------------------------
#include
#pragma comment(lib,"ws2_32")
#include
using namespace std;
int main()
{
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
sockaddr_in local;
SOCKET s;
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr("127.0.0.1");
local.sin_port=htons(22222);
s=socket(AF_INET,SOCK_DGRAM,0);
bind(s,(SOCKADDR *)&local,sizeof(local));
char buf[1];
int a=sizeof(local);
for(;;)
{
recvfrom(s,buf,sizeof(buf),0,(SOCKADDR *)&local,&a);
sendto(s,"hello",13,0,(SOCKADDR *)&local,a);
}
cout < return 0;
}
UDP有小小的不同在
socket(AF_INET,SOCK_DRGAM,0);
小小的變動
UDP的程式裡面少了list和accept ,TCP因為3方交握,所以龜毛的要確認來方.UDP就不用了,所以資料傳輸容易miss
//--------------------------------------------------------------------------
#include
#pragma comment(lib,"ws2_32")
#include
using namespace std;
int main()
{
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
sockaddr_in local;
SOCKET s;
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr("127.0.0.1");
local.sin_port=htons(22222);
s=socket(AF_INET,SOCK_DGRAM,0);
bind(s,(SOCKADDR *)&local,sizeof(local));
char buf[1];
int a=sizeof(local);
for(;;)
{
recvfrom(s,buf,sizeof(buf),0,(SOCKADDR *)&local,&a);
sendto(s,"hello",13,0,(SOCKADDR *)&local,a);
}
cout <
}
Socket with C
開個socket 就要 "include winsock2.h" 才有會個特異功能,這很正常的杯.
java 就要 import java.net.
而C的funtion裡面常有的縮寫
AF PF
PF -> protocaol family
其實沒啥差別
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW <--特別的方式可以聽到IP層的資料.如icmp
有趣的是socket(int,int,int)都可以是int型態.也就是給數字也通的樣子.
socket_in 是寫一些網路資訊的資料結構
可以利用bind 和 connect 的funtion去把socket和這些資料連接
bind 結合參數 <-多用於server
connect是連線 <-多用於client
listen(socket , int) <--當完成 bind 後就可以利用來等連線 ,後面的int為連線數
accept(socket,sockaddr,int) 接受連線 <--準備傳資料啦.當後面兩個arg都為 null的時候表示不介意連線的點為何.
最後到了傳送的部份是send 和 recv .
當然還有UDP用的recvfrom 和 sendto.<-UDP要對方位置
架構概念 和java有點不一樣
socket -> bind -> listen -> accept -> recv && send
sockaddr_in sockaddr_in
下面是這次寫的小範例,不過在檔案部份小懶惰,沒寫好,所以有要copy得人要小心一點
//------------------------------------------------------------------------//
#include
#include
#include
#include "winsock2.h"
#pragma comment(lib,"ws2_32")
using namespace std;
void main() {
char readc[100000];
ifstream inFile("aaa.cmp", ios::binary);
ofstream out("bbb.txt",ios::binary);
long nFileSize= inFile.tellg();
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
//-------------初始化 winsock很重要...沒有就不會動了
// Create a socket.
SOCKET m_socket;
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// Bind the socket.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
service.sin_port = htons( 27015 );
if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf( "bind() failed.\n" );
closesocket(m_socket);
return;
}
// Listen on the socket.
if ( listen( m_socket, 1 ) == SOCKET_ERROR )
printf( "Error listening on socket.\n");
// Accept connections.
SOCKET AcceptSocket;
printf( "Waiting for a client to connect...\n" );
int bytesSent=SOCKET_ERROR;
while (1) {
AcceptSocket = SOCKET_ERROR;
while ( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( m_socket, NULL, NULL );
}
printf( "Client Connected.\n");
m_socket = AcceptSocket;
break;
}
// Send and receive data.
while(inFile)
{
inFile.read(readc,100000);
bytesSent = send( m_socket, readc, 100000, 0 );
}
out.close();
inFile.close();
closesocket(m_socket);
}
java 就要 import java.net.
而C的funtion裡面常有的縮寫
AF PF
PF -> protocaol family
其實沒啥差別
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW <--特別的方式可以聽到IP層的資料.如icmp
有趣的是socket(int,int,int)都可以是int型態.也就是給數字也通的樣子.
socket_in 是寫一些網路資訊的資料結構
可以利用bind 和 connect 的funtion去把socket和這些資料連接
bind 結合參數 <-多用於server
connect是連線 <-多用於client
listen(socket , int) <--當完成 bind 後就可以利用來等連線 ,後面的int為連線數
accept(socket,sockaddr,int) 接受連線 <--準備傳資料啦.當後面兩個arg都為 null的時候表示不介意連線的點為何.
最後到了傳送的部份是send 和 recv .
當然還有UDP用的recvfrom 和 sendto.<-UDP要對方位置
架構概念 和java有點不一樣
socket -> bind -> listen -> accept -> recv && send
sockaddr_in sockaddr_in
下面是這次寫的小範例,不過在檔案部份小懶惰,沒寫好,所以有要copy得人要小心一點
//------------------------------------------------------------------------//
#include
#include
#include
#include "winsock2.h"
#pragma comment(lib,"ws2_32")
using namespace std;
void main() {
char readc[100000];
ifstream inFile("aaa.cmp", ios::binary);
ofstream out("bbb.txt",ios::binary);
long nFileSize= inFile.tellg();
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
//-------------初始化 winsock很重要...沒有就不會動了
// Create a socket.
SOCKET m_socket;
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
// Bind the socket.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
service.sin_port = htons( 27015 );
if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf( "bind() failed.\n" );
closesocket(m_socket);
return;
}
// Listen on the socket.
if ( listen( m_socket, 1 ) == SOCKET_ERROR )
printf( "Error listening on socket.\n");
// Accept connections.
SOCKET AcceptSocket;
printf( "Waiting for a client to connect...\n" );
int bytesSent=SOCKET_ERROR;
while (1) {
AcceptSocket = SOCKET_ERROR;
while ( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( m_socket, NULL, NULL );
}
printf( "Client Connected.\n");
m_socket = AcceptSocket;
break;
}
// Send and receive data.
while(inFile)
{
inFile.read(readc,100000);
bytesSent = send( m_socket, readc, 100000, 0 );
}
out.close();
inFile.close();
closesocket(m_socket);
}
星期三, 7月 05, 2006
星期二, 7月 04, 2006
C++ 歷史 with CLI
* BCPL (Basic Computer Programming Language)
* B (Ken Thompson, original UNIX work)
* C (Dennis Ritchie, adding type and control structure to B)
* C with Classes (~1979)
* C84 (~1984)
* Cfront, release E (~1984-to universities)
* Cfront, release 1.0 (1985-to the world )—20th birthday
* Multiple/Virtual Inheritance (MI) programming (~1988)
* Generic Programming (~1991) (templates)
* ANSI C++/ ISO-C++ (~1996)
* Dynamic Component programming (~2005) (C++/CLI)
* B (Ken Thompson, original UNIX work)
* C (Dennis Ritchie, adding type and control structure to B)
* C with Classes (~1979)
* C84 (~1984)
* Cfront, release E (~1984-to universities)
* Cfront, release 1.0 (1985-to the world )—20th birthday
* Multiple/Virtual Inheritance (MI) programming (~1988)
* Generic Programming (~1991) (templates)
* ANSI C++/ ISO-C++ (~1996)
* Dynamic Component programming (~2005) (C++/CLI)
pragma
在所有的預處理指令中,#Pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全相容的情況下,給出主機或作業系統專有的特徵。依據定義,編譯指示是機器或作業系統專有的,且對於每個編譯器都是不同的。
其格式一般為: #Pragma Para
其中Para 為參數,下面來看一些常用的參數。
(1)message 參數。 Message 參數是我最喜歡的一個參數,它能夠在編譯資訊輸出窗
口中輸出相應的資訊,這對於源代碼資訊的控制是非常重要的。其使用方法為:
#Pragma message(“消息文本”)
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。
當我們在程式中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
當我們定義了_X86這個宏以後,應用程式在編譯時就會在編譯輸出窗口裏顯示“_
X86 macro activated!”。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了
。
(2)另一個使用得比較多的pragma參數是code_seg。格式如:
#pragma code_seg( ["section-name"][,"section-class"] ] )
它能夠設置程式中函數代碼存放的代碼段,當我們開發驅動程式的時候就會使用到它。
(3)#pragma once (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在VC6中就已經有了,但是考慮到相容性並沒有太多的使用它。
(4)#pragma hdrstop表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈結的速度,但如果所有頭文件都進行預編譯又可能佔太多磁片空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關係,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先級,如果使用了#pragma package(smart_init) ,BCB就會根據優先級的大小先後編譯。
(5)#pragma resource "*.dfm"表示把*.dfm文件中的資源加入工程。*.dfm中包括表單
外觀的定義。
(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價於:
#pragma warning(disable:4507 34) // 不顯示4507和34號警告資訊
#pragma warning(once:4385) // 4385號警告資訊僅報告一次
#pragma warning(error:164) // 把164號警告資訊作為一個錯誤。
同時這個pragma warning 也支援如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
這裡n代表一個警告等級(1---4)。
#pragma warning( push )保存所有警告資訊的現有的警告狀態。
#pragma warning( push, n)保存所有警告資訊的現有的警告狀態,並且把全局警告
等級設定為n。
#pragma warning( pop )向棧中彈出最後一個警告資訊,在入棧和出棧之間所作的
一切改動取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在這段代碼的最後,重新保存所有的警告資訊(包括4705,4706和4707)。
(7)pragma comment(...)
該指令將一個註釋記錄放入一個對象文件或可執行文件中。
常用的lib關鍵字,可以幫我們連入一個庫文件。
每個編譯程式可以用#pragma指令激活或終止該編譯程式支援的一些編譯功能。例如,對迴圈優化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 終止
有時,程式中會有些函數會使編譯器發出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以這樣:
#pragma warn —100 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函數會產生一條有唯一特徵碼100的警告資訊,如此可暫時終止該警告。
每個編譯器對#pragma的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。
其格式一般為: #Pragma Para
其中Para 為參數,下面來看一些常用的參數。
(1)message 參數。 Message 參數是我最喜歡的一個參數,它能夠在編譯資訊輸出窗
口中輸出相應的資訊,這對於源代碼資訊的控制是非常重要的。其使用方法為:
#Pragma message(“消息文本”)
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。
當我們在程式中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
當我們定義了_X86這個宏以後,應用程式在編譯時就會在編譯輸出窗口裏顯示“_
X86 macro activated!”。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了
。
(2)另一個使用得比較多的pragma參數是code_seg。格式如:
#pragma code_seg( ["section-name"][,"section-class"] ] )
它能夠設置程式中函數代碼存放的代碼段,當我們開發驅動程式的時候就會使用到它。
(3)#pragma once (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在VC6中就已經有了,但是考慮到相容性並沒有太多的使用它。
(4)#pragma hdrstop表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈結的速度,但如果所有頭文件都進行預編譯又可能佔太多磁片空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關係,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先級,如果使用了#pragma package(smart_init) ,BCB就會根據優先級的大小先後編譯。
(5)#pragma resource "*.dfm"表示把*.dfm文件中的資源加入工程。*.dfm中包括表單
外觀的定義。
(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價於:
#pragma warning(disable:4507 34) // 不顯示4507和34號警告資訊
#pragma warning(once:4385) // 4385號警告資訊僅報告一次
#pragma warning(error:164) // 把164號警告資訊作為一個錯誤。
同時這個pragma warning 也支援如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
這裡n代表一個警告等級(1---4)。
#pragma warning( push )保存所有警告資訊的現有的警告狀態。
#pragma warning( push, n)保存所有警告資訊的現有的警告狀態,並且把全局警告
等級設定為n。
#pragma warning( pop )向棧中彈出最後一個警告資訊,在入棧和出棧之間所作的
一切改動取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在這段代碼的最後,重新保存所有的警告資訊(包括4705,4706和4707)。
(7)pragma comment(...)
該指令將一個註釋記錄放入一個對象文件或可執行文件中。
常用的lib關鍵字,可以幫我們連入一個庫文件。
每個編譯程式可以用#pragma指令激活或終止該編譯程式支援的一些編譯功能。例如,對迴圈優化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 終止
有時,程式中會有些函數會使編譯器發出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以這樣:
#pragma warn —100 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函數會產生一條有唯一特徵碼100的警告資訊,如此可暫時終止該警告。
每個編譯器對#pragma的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。
星期一, 7月 03, 2006
STL container
這邊要開始瞭解STL container的運作方式了
Container裡面使用的都是call by value
Step 1:
也是一般程式都應該要做的,就是initialization,有初始也就有解構.
Step 2:
Container裡面使用的都是call by value
Step 1:
也是一般程式都應該要做的,就是initialization,有初始也就有解構.
Step 2:
星期日, 7月 02, 2006
STL-PART II
STL 's componets
Containers (容器): This's to management the object of set, 每個 Containers 都會有各自的優點和缺點,也因為不同的需求有不同的類型.
Iterators (迭代器): 用來巡訪collection of objects
Algorithms (演算法): 故名思義
再來要學會怎用STL
可以先
#include
Containers (容器): This's to management the object of set, 每個 Containers 都會有各自的優點和缺點,也因為不同的需求有不同的類型.
Iterators (迭代器): 用來巡訪collection of objects
Algorithms (演算法): 故名思義
再來要學會怎用STL
可以先
#include
去使用看看 使用方式和tempelate蠻像的
list<型態> variable
之後就像一般的物件方式使用,感覺還蠻愉快的.
STL(Standard Template Library)
果然,之前想到的現在果然碰到了.一切都還是要標準化.
本次參考書為侯捷譯的C++標準函式庫.
首先就是要會用杯
然後瞭解
最後就是X他啦
最X的STL應該就是好用 安全 速度快吧?之後大概是Generic Programming
------------------------------------------------------------------------
STL六個組件container algorithm iterator adapterr functor allocator
Generic 要符合 Template 的形式所以程式庫內所有的東西都被設計為Template
初探 End..
本次參考書為侯捷譯的C++標準函式庫.
首先就是要會用杯
然後瞭解
最後就是X他啦
最X的STL應該就是好用 安全 速度快吧?之後大概是Generic Programming
------------------------------------------------------------------------
STL六個組件container algorithm iterator adapterr functor allocator
Generic 要符合 Template 的形式所以程式庫內所有的東西都被設計為Template
初探 End..
訂閱:
文章 (Atom)