??xml version="1.0" encoding="utf-8" standalone="yes"?> There are various ways to get the passwords stored in KeePass into other windows. The first, and most simple method is copying them to the clipboard. For this, just double-click onto the specific field in the main password list. Example: if you want to copy the password of entry X, point onto the password field of the entry in the main view and double-click. The password is copied to the clipboard. If you enable the auto-clearing option, KeePass will clear the clipboard automatically after some seconds. This prevents you from forgetting to clear the clipboard yourself, leaving sensitive data in the clipboard. The second method is drag-n-drop. As in method 1, point onto the field you want to use, click the left mouse button and hold it. Drag the data into other windows. The third, and the most powerful method is auto-type. KeePass features a very mighty auto-type feature, which types user names, passwords, etc. into other windows for you. The default auto-typing sequence is: {USERNAME}{TAB}{PASSWORD}{TAB}{ENTER}. But this sequence is customizable, per entry (read the CHM documentation file that comes with KeePass for more about this). This makes the auto-type feature applicable to all windows and webforms you'll ever see. There are two submethods to perform an auto-type:
{
int co;
};
class Base1: virtual public CommonBase
{
public:
virtual void print1() {}
virtual void print2() {}
private:
int b1;
};
class Base2: virtual public CommonBase
{
public:
virtual void dump1() {}
virtual void dump2() {}
private:
int b2;
};
class Derived: public Base1, public Base2
{
public:
void print2() {}
void dump2() {}
private:
int d;
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
F5~译之,你会惊奇地发玎ͼOutput里面有如下字P
2 +---
3 | +--- (base class Base1)
4 0 | | {vfptr}
5 4 | | {vbptr}
6 8 | | b1
7 | +---
8 | +--- (base class Base2)
9 12 | | {vfptr}
10 16 | | {vbptr}
11 20 | | b2
12 | +---
13 24 | d
14 +---
15 +--- (virtual base CommonBase)
16 28 | co
17 +---
18
19 Derived::$vftable@Base1@:
20 0 | &Base1::print1
21 1 | &Derived::print2
22
23 Derived::$vftable@Base2@:
24 0 | &Base2::dump1
25 1 | &Derived::dump2
26
27 Derived::$vbtable@Base1@:
28 0 | -4
29 1 | 24 (Derivedd(Base1+4)CommonBase)
30
31 Derived::$vbtable@Base2@:
32 0 | -4
33 1 | 12 (Derivedd(Base2+4)CommonBase)
34
35 Derived::print2 this adjustor: 0
36 Derived::dump2 this adjustor: 12
看到了吗? VC8居然输出了Derived对象的完整布局! 我们l于可以不必两眼一抚w般的去peek/poke?...W?行表明,Derived对象d用了32字节Q其׃部分l成Q分别是?-?、行 8-?2、行13、行28Q其中前二者分别是基类Base1、Base2的布局Q最后的?8拟基cCommon的布局?br />
以基c?Base1部分ZQ可发现其由一个虚函数表指针vftable和虚指针vbtable构成Q先看Base1部分的vftable所指向的虚? vftable@Base1(?9)Q不隑֏玎ͼ其中的表?已经被Derived::print2loverride了;再来看Base2部分?vftable所指向的虚?vftable@Base2(?3)Q可发现Q同LQBase2::dump2被Derived::dump2l?override了。这不明摆着是虚函数机制嘛Qheh~
值得注意的是Q这个例子同时说明,多承场合下Q其实在单一对象中是存在多个 this指针?...?5-36l出了如何将Derived的this指针校正为其基类子对象this指针的偏U量Q也是_Ҏ?6Q假设有?Derived dQ那么d.dump1()实际上应该理解成通过虚表$vftable@Base2?(Base2*)(((char*)&d)+12))- >dump1()的调?...即传递给所有Base2成员函数的this指针应该?Base2*)((char*)(&d)+12)Q这里可能我写得恐怖了点,意思到了就?...q不Q普通ѝ多l承、对象Slicing的语义都在这个布局里面了,看仔l了哈~
OKQ多l承看完了,l箋看虚拟基cL如何布局的。虚基Common在Derived的布局中,位于Derived本n数据成员之后的位|。Base1?Base2中均保存了一个vbtable指针Q其分别指向各自所使用的虚$vbtable@Base1?vbtable@Base2Qؓ什么要指向一个虚? 很简单,因ؓBase1、Base2有可能会同时l承多个不同的虚拟基c?....q充分体CC++对象布局的复杂?...在每个虚中,保存了所l承的虚拟基c部分相对于子类部分vbtable指针的偏Ud|以Base2ZQ我们知道Base2的vbtable在Derived中的偏移gؓ16 (?0)Q则Ҏ$vbtable@Base2Q虚基Common部分距离Base2 vbtable指针的偏Udgؓ12,则有虚基Common在Derived中的dUdgؓ16+12。与普通多l承同理Q我们在调用非虚拟的虚基成员函数Ӟ必须Derived的this指针调整为指向虚基部分的this指针Q只有这h能成功地讉K虚基自n的数据成员和虚基的虚拟函?通过虚基自己?vftableQؓ单v见,上例中我没弄那么复杂了Q大家可以自q玩,明白如何举一反三卛_)
]]>
]]>
#include <boost/bind.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
template<class T>
inline T & ToRef( T *pT)
{
return *pT;
}
#define TODEF(x) bind( ToRef<x>, _1)
template<class T>
inline void DeletePointer( T *pT)
{
delete pT;
}
#define ALL(v) (v).begin(), (v).end()
struct X
{
public:
int m_t;
X():m_t(11)
{
}
bool f(int a)
{
std::cout << m_t << std::endl;
return true;
}
};
int main()
{
using namespace boost;
using namespace std;
vector<X *> v;
for( int i=0; i<10; ++i)
v.push_back( new X);
for_each( ALL(v), bind(&X::f, TODEF(X), 4 ) );
for_each( ALL(v), bind( DeletePointer<X>, _1) );
return 0;
}
上帝把两羊攑֜草原上,一在南,一在北?/span>
上帝q给群找了两种天敌Q一U是狮子Q一U是狹{?/span>
上帝对羊说:“如果你们要狼Q就l一只,d随意咬你们?/span>
如果你们要狮子,q两头Q你们可以在两头狮子中Q选一_q可以随时更换?#8221;
q道题的问题是Q如果你也在群中,你是选狼q是选狮子?
很容易做出选择吧?
好吧Q记住你的选择Q接著往下看?/span>
南边那群想,狮子比狼凶猛得多,q是要狼吧。于?/span>,它们p了一只狼?/span>
北边那群想Q狮子虽然比狼凶猛得多,但我们有选择权,q是要狮子吧。于是,它们p了两头狮子?/span>
那只D了南边的群后,开始吃?/span>
Dn体小Q食量也,一只羊够它吃几天了?/span>
q样群几天才被q杀一ơ?/span>
北边那群挑选了一头狮子,另一头则留在上帝那里?/span>
q头狮子q入群?/span>,也开始吃。狮子不但比狼凶猛,而且食量惊hQ每天都要吃一只羊?/span>
q样群天天都要被q杀Q惊恐万状?/span>
群赶紧请上帝换一头狮子。不料,上帝保管的那头狮子一直没有吃东西Q正饥饿难?/span>,它扑q羊,比前面那头狮子咬得更疯狂?/span>
群一天到晚只是逃命Q连草都快吃不成了?/span>
南边的羊庆q自己选对了天敌,又嘲W北边的群没有眼光?/span>
北边的羊非常后悔,向上帝大倒苦?/span>,要求更换天敌Q改要一只狼?/span>
上帝_“天敌一旦确定,׃能更?/span>,必须世代盔R,你们唯一的权利是在两头狮子中选择?#8221;
北边的羊只好把两头狮子不断更换?/span>
可两头狮子同样凶D,换哪一头都比南边的群悲惨得多Q它们烦性不换了,让一头狮子吃得膘肥体?/span>,另一头狮子则饿得_?/span>
眼看那头瘦狮子快要饿M,群才请上帝换一头?/span>
q头瘦狮子经q长旉的饥饿后,慢慢悟出了一个道?/span>:
自己虽然凶猛异常,一癑֏都不是Ҏ,可是自己的命q是操纵在羊手里的?/span>
群随时可以把自己送回上帝那里,让自己饱受饥饿的煎熬,甚至有可能饿歅R?/span>
想通这个道理后,瘦狮子就对羊特别客?/span>,只吃ȝ和病?/span>,凡是健康的羊它都不吃了?/span>
群喜出望外,有几只小提议干脆固定要瘦狮?/span>,不要那头肥狮子了?/span>
一只老公提醒说:“瘦狮子是怕我们送它回上帝那里挨?/span>,才对我们q么好?/span>
万一肥狮子饿M,我们没有了选择的余?/span>,瘦狮子很快就会恢复凶D的本性?#8221;
群觉得老羊说得有理,Z不让另一头狮子饿?/span>,它们赶紧把它换回来?/span>
原先膘肥体壮的那头狮?/span>,已经饿得只剩下皮包骨头了,q且也懂得了自己的命q是操纵在羊手里的道理?/span>
Z能在草原上待久一?/span>,它竟百般讨好L来。而那头被送交l上帝的狮子,则难q得下了眼泪?/span>
北边的羊在l历了重重磨隑,l于q上了自p在的生活?/span>
南边的那羊的处境却来悲惨了,那只狼因为没有竞争对?/span>,群又无法更换它,
它就胡作非ؓ,每天都要咬死几十只羊,q只狼早已不吃羊肉了,它只喝羊心里的血?/span>
它还不准叫,哪只叫就立刻咬死哪只?/span>
南边的羊只能在心中哀?/span>:“早知道这Pq不如要两头狮子?#8221;