扫描局域网内所有主机(禁止ping的主机无法显示)起初是为了查当前网段可用的IP,增加手动设置IP的成功率,之后有了 NuTs IWantIP就基本不用了不过用来查主机与IP映射还是很快的程序采用多线程,速度很快~
NuTs Login&Out
科大专用上网登录程序学校校园网实行实名制,每个同学上网都要到特定网页输入学号和密码,这本来挺好的,可问题是,当用户关机的时候如果不注销帐号,那么当下次开机,IP改变后,无法访问任何网页,提示说帐号被上一个IP占用,而上一个IP如果恰好又被别人使用,那么那个人就可以使用你的帐号上网. 而你只有哭的份了 (幸好学校上网不收费)于是我写了这个登录/注销程序. 程序会在关机/重启/注销时自动注销上网帐号,这样就可以避免上述问题.程序还可以定时检测网络连通性(ping baidu.com)并刷新arp缓存. 这样可以解决arp欺骗导致的无法上网的问题.(宿舍楼的arp欺骗很严重~)这个程序还是很好用滴,不过在离开科大后就再也用不上了.科大的同学可以在 http://city.ibeike.com 的编程板块(还是软件,我忘了)找到下载
C++函数调用中的引用和指针
C++初学者对函数调用中的引用总是感到十分迷惑
下面就研究一下
先看下面三个函数
void f1(int a,intb) //按值传递
{
a=0;
b=3;
}
void f2(int &a,int &b) //按引用传递
{
a=0;
b=3;
}
void f3(int *a,int *b) //按指针传递
{
*a=0;
*b=3;
}
要想知道他们之间的区别,最好的方法是看看编译器究竟干了什么
用cl.exe 的-Fa参数,生成对应源代码的汇编代码,摘要如下
按值传递
PROC NEAR
push ebp
mov ebp, esp
;直接将压入栈的2个参数赋值为0和3
mov DWORD PTR _a$[ebp], 0
mov DWORD PTR _b$[ebp], 3
pop ebp
ret 0
按引用传递
PROC NEAR
push ebp
mov ebp, esp
;将压入栈的参数作为指针,将0和3赋值给指针所指向的内存单元
mov eax, DWORD PTR _a$[ebp]
mov DWORD PTR [eax], 0
mov ecx, DWORD PTR _b$[ebp]
mov DWORD PTR [ecx], 3
pop ebp
ret 0
按指针传递
PROC NEAR
push ebp
mov ebp, esp
;可以看到,按引用传递和按指针传递的汇编代码一模一样
;但是使用引用,我们不必再用星号解引用了,这样提高了代码的可读性
;语言层面,引用的用法和对象一样;在二进制层面,引用一般都是通过指针来实现的,
;只不过编译器帮我们完成了转换
mov eax, DWORD PTR _a$[ebp]
mov DWORD PTR [eax], 0
mov ecx, DWORD PTR _b$[ebp]
mov DWORD PTR [ecx], 3
pop ebp
ret 0
引用既具有指针的效率,又具有变量使用的方便性和直观性
我的小程序NuTs Launcher
C++、Java、Delphi类继承的对比
总体来说
- c++: 完全的控制,极大的灵活性,灵活带来的复杂
- java:比c++"保守",虚拟机风格的体系结构
- delphi:很保守
inclusion/using clause
#include <iostream>
using namespace std;
import java.io.*;
uses windows,system,sysutils;
inheritance
class Child:[public | protected | private] Fahter,public Mother{
...
}
C++是这三种语言中继承最为复杂的.
分为 public,protected,private继承,同时支持真正的多继承
public继承(又称类型继承)和java的继承一样,保持父类的访问控制
protected继承将父类public成员改变为protected的
private继承(又称实现继承)不直接支持父类的公有接口,而提供自己的公有接口
所以private继承中,子类将父类中原先的protected成员和public成员都置为private的
所以原则上private继承中的子类应该是继承树中的叶节点,它只有private和public成员而
没有protected成员.它不应该再被继承,类似于Java中的final class
class Child extends Father implements IInterface{
...
}
TChild = class(TFather,IInterfacedObject)
...
end;
java 和 delphi 的继承相似,都是单继承同时可以实现多个接口
Access Control/Organization
class Foo{
private:
int i;
int j;
void f();
protected:
int k;
public:
int o;
}
class Foo /* extends Object */ {
private
int i;
int j;
void f(){...};
protected
int k;
public
int o;
}
TFoo = class(TObject)
private
i:Integer;
j:Integer;
protected
k:Integer;
public
o:Integer;
publicshed
property
Tag:Integer read i write i;
end;
如果不给出访问控制,
c++默认是private
java默认是包内可见的
delphi默认是public的(单元内可见?)
c++的访问控制和代码管理最为丰富:
可以通过#include包含c/cpp头文件,提供向c的兼容
同时可以使用名字空间防止名字冲突,并且像c一样将代码分为头文件和实现文件
同时丰富性也带来了复杂性.使得c++的文件组织没有java和delphi清晰
java提供了松散的代码组织方式–包(package),而delphi提供了单元的代码组织方法
这两种组织方法相似,都是给了我们一个存放一组相关类的地方.而这个地方,在java中
是一个文件系统上的文件夹,在delphi中是一个单元文件
相比之下,我还是喜欢Delphi的组织方法:当类很多的时候java包中的文件变得既多又不好管理
虚函数 vs 动态函数
C++中有虚函数。而Delphi中既有虚函数还有动态函数。二者在语义上是等价的。
Virtual and dynamic methods are semantically equivalent. They differ only in the implementation of method-call dispatching at runtime.
区别在于虚函数优化了速度,而动态函数优化了代码大小
Virtual methods optimize for speed, while dynamic methods optimize for code size.
In general, virtual methods are the most efficient way to implement polymorphic behavior.
总体上来讲,虚函数是实现多态行为的最有效的方法
Dynamic methods are useful when a base class declares many overridable
methods which are inherited by many descendant classes in an application, but only
occasionally overridden.
当基类声明了很多可重写但是很少重写的方法时使用动态函数,
这样可一减小代码大小。在设计Framework时常使用这个技术
MFC学习笔记#1
作为Windows的Framework需要解决的一个问题就是
消息映射 Message Mapping
Delphi中由于有编译器的支持,可以直接在用户编写的类中处理需要处理的消息:
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
在MFC中就比较复杂了. afx使用宏来实现Windows消息到处理函数的映射而没有使用会带
而外的开销:由于C++中实现虚函数需要一个分发表vtable,而无论子类是否重写父类的虚函数,
都需要4个字节的开销.在CWnd类中至少要处理100个以上的消息.这样设计会带来很大的问题.
afx用一组宏将用于消息映射的数据保存在类中.大概情况是:记录该类可以处理的Windows消息,
当消息来到时,对比自己可以处理的消息列表,如果可以处理,就交给列表中记录的函数来处理.
而这个函数就是我们自己些的.比如 OnLButtonDown等
afx.h 中声明了mfc中最基础的类
struct CRuntimeClass; // object type information
class CObject; // the root of all objects classes
class CException; // the root of all exceptions
class CArchiveException; // archive exception
class CFileException; // file exception
class CSimpleException;
class CMemoryException; // out-of-memory exception
class CNotSupportedException; // feature not supported exception
class CFile; // raw binary file
class CStdioFile; // buffered stdio text/binary file
class CMemFile; // memory based file
// Non CObject classes
class CString; // growable string type
class CTimeSpan; // time/date difference
class CTime; // absolute time/date
struct CFileStatus; // file status information
struct CMemoryState; // diagnostic memory support
class CArchive; // object persistence tool
class CDumpContext; // object diagnostic dumping
先看一下CRuntimeClass
struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;//保存类名
int m_nObjectSize;//类对象大小
UINT m_wSchema; // schema number of the loaded class//是否可序列化
CObject* (PASCAL* m_pfnCreateObject)(); // 指向类的构造函数的指针
//指向父类CRuntimeClass的指针
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif
// Operations
CObject* CreateObject(); //动态创建
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; //类型鉴别
// Implementation
void Store(CArchive& ar) const; //序列化
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum) ;//"反序列化"
// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes //注册类列表
};
CRuntimeClass 是MFC中很重要的一个类,动态创建实例是最常用的功能之一
// Helper macros for declaring CRuntimeClass compatible classes
#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name)
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static const AFX_DATA CRuntimeClass class##class_name;
virtual CRuntimeClass* GetRuntimeClass() const;
#define _DECLARE_DYNAMIC(class_name)
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
static AFX_DATA CRuntimeClass class##class_name;
virtual CRuntimeClass* GetRuntimeClass() const;
#else
#define DECLARE_DYNAMIC(class_name)
public:
static const AFX_DATA CRuntimeClass class##class_name;
virtual CRuntimeClass* GetRuntimeClass() const;
#define _DECLARE_DYNAMIC(class_name)
public:
static AFX_DATA CRuntimeClass class##class_name;
virtual CRuntimeClass* GetRuntimeClass() const;
#endif
// not serializable, but dynamically constructable
#define DECLARE_DYNCREATE(class_name)
DECLARE_DYNAMIC(class_name)
static CObject* PASCAL CreateObject();
#define _DECLARE_DYNCREATE(class_name)
_DECLARE_DYNAMIC(class_name)
static CObject* PASCAL CreateObject();
#define DECLARE_SERIAL(class_name)
_DECLARE_DYNCREATE(class_name)
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);
CObject
基本服务:
BOOL IsSerializable() const;
BOOL IsKindOf(const CRuntimeClass* pClass) const; //类型鉴别
// Overridables
virtual void Serialize(CArchive& ar); //序列化
// Diagnostic Support //诊断支持
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
//动态创建,利用CRuntimeClass里的m_pfnCreateObject
CObject* CRuntimeClass::CreateObject()
CWnd 在afxwin.h中定义,在wincore.cpp中实现
CWnd封装的功能
// Window tree access
// Message Functions
// Message processing for modeless dialog-like windows
// Window Text Functions
// CMenu Functions - non-Child windows only
// Window Size and Position Functions
// Coordinate Mapping Functions
// Update/Painting Functions
// Timer Functions
// ToolTip Functions
// Window State Functions
// Dialog-Box Item Functions
// Scrolling Functions
// Window Access Functions
// Alert Functions
// Clipboard Functions
// Caret Functions
// Shell Interaction Functions
// Icon Functions
// Context Help Functions
// Dialog Data support
// Help Command Handlers
// Layout and other functions
// OLE control wrapper functions
/* 消息处理函数 */
// Window-Management message handler member functions
// Nonclient-Area message handler member functions
// System message handler member functions
// Input message handler member functions
// Initialization message handler member functions
// Clipboard message handler member functions
// Control message handler member functions
// MDI message handler member functions
// Menu loop notification messages
Windows 控件的实现文件在 winctrl1.cpp~winctrl7.cpp
初识lambda
lamda{||block} ->aProc
Kernel::Proc的同义语
lamda{block} 等价于 proc{block}
例子:
print "(t)imes or (p)lus: "
times = gets
print "number: "
number = Integer(gets)
if times =~ /^t/
calc = lambda {|n| n*number }
else
calc = lambda {|n| n+number }
end
puts((1..10).collect(&calc).join(", "))
15:39 2008-3-17 补充
Python中的lambda:
def make_repeater(n):
return lambda s: s*n
twice = make_repeater(2)
print twice("word")
c:> wordword
Python中的lambda只能使用expression,不能使用statement
在Delphi中使用MSVC函数
在Delphi 例程中没有类似于C中的system
函数
int system(const char* command);
用下面的方法可以让你在Delphi中使用msvc runtime的函数
program YourProg;
function system(command:PChar):Integer;cdecl;external "msvcrt.dll" name "system";
begin
system("pause");
end.
wxRuby2的安装与Demo程序
用gem安装wxruby2
c:>gem install wxruby2-preview
在文件前面增加下列代码
begin
require "wx"
rescue LoadError => no_wx_err
begin
require "rubygems"
require "wx"
rescue LoadError
raise no_wx_err
end
end
测试:
class TroutApp < Wx::App
def on_init
frame = Wx::Frame.new(nil, -1, "Tiny wxRuby Application")
panel = Wx::StaticText.new(frame, -1, "You are a trout!",
Wx::Point.new(-1,1), Wx::DEFAULT_SIZE,
Wx::ALIGN_CENTER)
frame.show
end
end
TroutApp.new.main_loop
update:
FOX界面库
require "fox16"
include Foxapplication = FXApp.new("Hello", "FoxTest")
application.init(ARGV)
main = FXMainWindow.new(application, "Hello", nil, nil, DECOR_ALL)
FXButton.new(main, "&Hello, World!", nil, application, FXApp::ID_QUIT)
application.create()
main.show(PLACEMENT_SCREEN)
application.run()