2008年11月27日 星期四

Structure VS. Class

昨天看到一篇文章比較.NetFramework的Sructure和class
我把重點整理一下:
(1)struct是value type, class是reference type。所以一樣的data member struct會比class小一點(少消耗了位址空間)
例如:

Class c1
Private Integer a
Private Integer b
End Class

Struct s1
Private Integer a
Private Integer b
End Struct

Dim x as new c1()
Dim y as s1

x會比y大。因為x會比y多佔一個指向x的data member的位址。
(2)struct在CallByValue傳遞時會複製整個結構成員, class則只會copy位址,但是兩個位址會指到相同記憶體區塊
也就是說即使是ByVal對class的instance來說還是同等ByRef!
(3)class因屬reference type,需額外負擔Garbage collection回收、heap管理機制
這一點struct就把class比下去了
(4)成員函式(method member)不影響評估struct與class
對這兩個來說,成員函式都只會存在一副,不管今天有幾個instance
(5)成員變數少(小)時,用struct會比較有利
這點呼應(3),但是如果很大時可以考慮用class
(6)struct不能繼承
要用到繼承只能靠class
(7)對事件處理,struct比class有更多限制
WithEventsHandles 這兩個關鍵字不可套在struct中

2008年11月10日 星期一

為專案加上Log

應用範圍:
隨時記錄AP的運作狀況,以確定它正常運作。
記錄錯誤發生時的各項資訊,以利之後的Debug作業。
供使用者查詢應用程式運作的記錄。(或是應用程式無法運作時的回報記錄)
錯誤發生時通知相關人員處理問題。

步驟:
1.下載Log4net Library http://logging.apache.org/log4net/download.html
2.專案加入Log4net.dll(檔案於解壓縮資料夾下,bin\net\2.0\release)
3.在你的專案加入應用程式組態檔(App.config)[若是web專案的話,請加入在web.config],並加入下面組態:
  












































PS.Log方式除上面的FileLog及ApplicationEventLog外,還有資料庫(DB2,MS SQL ...),UDP ....
有需要其它Log方式的話,請參照http://logging.apache.org/log4net/release/config-examples.html

基本上,一個logger內會設定一個level;但可以設定多個appender-ref.

4.在專案中,加入Log:
  
Public Class Form1
Private Log As Log4Net.ILog

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Log4Net.Config.XmlConfigurator.Configure()
Log = Log4Net.LogManager.GetLogger("LoggingExample")

Log.Info("INFO Message")
Log.Warn("WARN Message")
Log.Debug("DEBUG Message")
Log.Fatal("FATAL Message")
Log.Error("ERROR Message!")
End Sub
End Class


5. 執行的結果,會寫到文件(rolling-log-20081110.log)及系統事件簿中的應用程式事件中;文件的部份內容如下:
[Header]
2008-11-07 16:23:42,862 [10] INFO LoggingExample [file:D:\Job\VACSS\Program\Server\Log4Net\Log4Net\Form1.vb (line:8)] - INFO Message
2008-11-07 16:23:42,908 [10] WARN LoggingExample [file:D:\Job\VACSS\Program\Server\Log4Net\Log4Net\Form1.vb (line:9)] - WARN Message
2008-11-07 16:23:42,908 [10] DEBUG LoggingExample [file:D:\Job\VACSS\Program\Server\Log4Net\Log4Net\Form1.vb (line:10)] - DEBUG Message
2008-11-07 16:23:42,908 [10] FATAL LoggingExample [file:D:\Job\VACSS\Program\Server\Log4Net\Log4Net\Form1.vb (line:11)] - FATAL Message
2008-11-07 16:23:42,908 [10] ERROR LoggingExample [file:D:\Job\VACSS\Program\Server\Log4Net\Log4Net\Form1.vb (line:12)] - ERROR Message!
[Footer]

你可以在App.config中,宣告多告logger,在不同狀況下使用不同的記錄log方式。

2008年11月9日 星期日

C++ 中的 struct 與 class 的比較


struct a : public b {
int foo_bar() {...;}
};


C++ 中的 struct 與在C語言中的struct不同
差別在於對於所繼承的類別預設存取權限的不同
struct 是 public
class 是 private

感謝秉宏大大提供正解

Reference:C++中的struct專題研究

在C++ primer一書中也有相當清楚的講解

2.8 使用關鍵字 struct P.66:
C++ 支援的另一個關鍵字也可以用來定義class型別。
...
以關鍵字class或struct定義出來的class,彼此之間唯一的差異是其預設存取層級:
struct的預設層級是public,class的預設層級是private。

15.2.5 繼承保護類別(Default Inheritance Protection Level) P.574:
如果你認為「以關鍵字struct定義」和「以關鍵字class定義」的classes另有更深層的差異,
不對,唯一差異就是成員的預設保護級別,以及衍生動作的預設保護級別。

2008年11月5日 星期三

在Web環境下快速彈出新視窗

傳統彈出新視窗的作法
都是用Javascript的window.open()method
但是它反應時間還蠻慢的
其實如果客戶的標準瀏覽器是IE
我們可以改用window.showModalDialog() or window.showModelessDialog()
兩個function的差別是showModalDialog() 彈出的視窗沒關掉前不能操作主畫面(類似對話框alert)

語法:
vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])
(1)vReturnValue: 子視窗的傳回值
(2)sURL: 子視窗的URL (必要項)
(3)vArguments: 傳入子視窗的參數(非必要)
(4)sFeatures: 視窗外觀屬性(字串型別)

舉個例子:
在主畫面TextBox填入值,按下送出按鈕把值傳到彈出的子畫面的TextBox中,同樣的,在子畫面也可以傳回值給主畫面。

主畫面的script:

function OpenNewWindow() {
var returnObj
var passingValue=document.getElementById('PareText1').value;

//開啟子畫面傳入本身視窗
returnObj=window.showModalDialog("PopWindow.aspx",self,'dialogHeight:100px;');
//讀取子畫面的回傳並填入母畫面
document.getElementById('PareText2').value=returnObj.returnValue;
}

子畫面的Script:

//來自母畫面的參數
var Parent=window.dialogArguments;
//要回傳的參數
var returnObj=Object();

//讀取母畫面的參數並塞值
document.getElementById('ChilText1').value=Parent.document.getElementById('PareText1').value;

function ReturnToParent() {
//把值腮入欲傳回的Object
//把Object傳回母畫面
returnObj.returnValue=document.getElementById('ChilText2').value;
window.returnValue=returnObj;
window.close();
}

說明:
1. window.dialogArguments是當呼叫showModalDialog()有傳入參數時才有值..(即"self")
2. var returnObj=Object();是Javascript宣告物件的語法,宣告之後就可以指定屬性值
如:returnObj.returnValue=document.getElementById('ChilText2').value;
3. window.returnValue就是指定showModalDialog()的傳回值

2008年11月3日 星期一

socket => address already in use

當 client 仍與 server 連接時,server 若重新啟動,
如果出現 address already in user 的 error 表示,
由於沒有正常 close socket ,
所以 socket 仍在使用該條 socket 並等待 client 的 FIN 封包,
解決辦法是將該 socket 設定為可重複使用,
需在建立 socket 後且使用 bind 前設定,


int opt = 1;
setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));


Reference: http://www.diybl.com/course/6_system/linux/Linuxjs/2008630/129368.html