??xml version="1.0" encoding="utf-8" standalone="yes"?> l常听到有h在抱怨这个语a哪里哪里不好Q那个语a又是如何的优U。对于这L牢骚Q我只是一W而过?/span> 我而言Q语a只是工具Q没有好坏之分。只要你采用相应的语aQ完成对应的工作Q那你的目标完成了。我们无需抱怨这U语a的缺点,而是应该抱有接受的态度。Q何语a的存在都有它的合理性,如果不合理是不会l受住时间的考验的。世间之物都h双面性,只是看利多还是弊大。如果一个东西是十全十美的,那我毫不犹U的告诉你Q一U情冉|它不存在Q另一U情冉|你还没发现它的缺炏V?/span> 每种语言都有自己得天独厚的优势,当然~点同时伴存?span style="font-family: Calibri; ">C语言是计机界的帔R藤?span style="font-family: Calibri; ">C语言执行效率高,用于写底层的驱动那是再适合不过。指针是C语言的精华。?span style="font-family: Calibri; ">C++是很强大的,只要你是个高手,你几乎可以利?span style="font-family: Calibri; ">C++完成M事情。当然虚函数?span style="font-family: Calibri; ">C++的精华?span style="font-family: Calibri; ">Java取消了指针,q是应该喜还是忧。喜的是Q没?span style="font-family: Calibri; ">C或?span style="font-family: Calibri; ">C++那种对内存繁琐的操作Q而且也降低了很多致命性的错误发生的概率。忧的是Q效率大打折扣,采用虚拟机的方式使得Java有跨q_的特性,必然会得效率降低。另外一个方面,你借别人的东西使用Q内存)Q是不是应该q回dQ从q一斚w考虑Q?span style="font-family: Calibri; ">C或?span style="font-family: Calibri; ">C++的设计思想更有意义。经常关?span style="font-family: Calibri; ">TIOBE世界~程语言排行榜,Java已经有很久排名第一Q我觉得q样的排名只是看看而已Q无需q多的信奉。下面看看几U主要语a的优~点?/span> C语言 C语言的优点: 1.z紧凑、灵zL?/span> 2.q算W丰?/span> 3.数据l构丰富 4. C是结构式语言 5. C语法限制不太严格Q程序设计自由度?/span> 6. C语言允许直接讉K物理地址Q可以直接对gq行操作 7. C语言E序生成代码质量高,E序执行效率?/span> 8. C语言适用范围大,可移植性好 9. C语言有一个突出的优点是适合于多U操作系l?span style="font-family: Calibri; ">,?span style="font-family: Calibri; ">DOS?span style="font-family: Calibri; ">UNIX,也适用于多U机?/span> 10.有效地将一个较复杂的程序系l设计Q务分解成许多易于控制和处理的子Q务,便于开发和l护 C语言的缺点: 1. C语言的缺点主要是表现在数据的装性上Q这一点?span style="font-family: Calibri; ">C在数据的安全性上做的有很大缺Pq也?span style="font-family: Calibri; ">C?span style="font-family: Calibri; ">C++的一大区别?/span> 2. C语言的语法限制不太严|对变量的cdU束不严|影响E序的安全性,Ҏl下标越界不作检查等。从应用的角度,C语言比其他高U语a较难掌握?/span> 3.可重用性差 4.数据安全性差 5.难以开发大型Y件和囑Ş界面的应用Y?/span> 6.把数据和处理数据的过E分Mؓ怺独立的实?/span> 7.当数据结构改变时Q所有相关的处理q程都要q行相应的修?/span> 8.每一U相对于老问题的新方法都要带来额外的开销 9.囑Ş用户界面的应用程序,很难用过E来描述和实玎ͼ开发和l护也都很困?/span> C++ C++优点Q?/span> 1.可扩展性强 2.高效 z?快?/span> 3.可移植?/span> 4.面向对象的特?/span> 5.强大而灵zȝ表达能力和不输于C的效?/span> 6.支持g开?br />7.E序模块间的关系更ؓ单,E序模块的独立性、数据的安全性就有了良好的保?/span> 8.通过l承与多态性,可以大大提高E序的可重用性,使得软g的开发和l护都更为方?/span> C++~点Q?/span> 1.比较底层Q易用性不是很?/span> 2.多重l承和友元机?/span> 3.标准库涵盖范围不?br />4.开发周期长 5.非ƈ?/span> 6.掌握有难?/span> 7._度装不够 Java Java的优点: 1.单?/span> 2.面向对象性(面向对象的程度可以达?5%Q?/span> 3.健壮?/span> 4.跨^台?/span> 5.高性能Q自动垃圑֛收机Ӟ 6.多线E?/span> 7.动态?/span> 8.安全?/span> Java的缺点: 1.效率低(毋庸|疑Q?/span> 2.跨^台是它最大的优点也是最大的~点 3.复杂性(做一个项目需要很多的知识Q涉及面q) 很多时候,一U语a的优点很可能是它的缺点,~点又可能是它的优点。这主要看你是从哪方面去考虑。这印证了那句话,凡事没有必然?/span> 不管是哪U语aQ就像文章开头所aQ只要你采用他达C惌的,那就成功了。无需q多在意它的~点Q更无需赞扬它的优点。所以网上那些关于哪U语a更好的口水仗Q我只能说这L争斗毫无意义?/span> 语言只是工具Q没有好坏之?/span> |上关于此类的讨论非常多Q发现对于该问题的理解各有各的说法,而各个说法中又相ȝq。通过览q些讨论以及寏VO'Reilly - UML 2.0 In A Nutshell (2007)》的参考,发表一下自q看法 c间关系有很多种Q在大的cd上可以分ZU:U向关系、横向关pR?/p> U向关系是l承关系Q它的概念非常明,也成为OO的三个重要特征之一Q这里不q多的讨论?/p> 横向关系较ؓ微妙Q按照UML的徏议大体上可以分ؓ四种Q?/p> 它们的强弱关pL没有异议的:依赖 < 兌 < 聚合 < l合 然而它们四个之间的差别却又不那么好拿捏Q需要好好体会?/p>
]]>E序员的奋斗Ԍ一Q?#8212;—谈几种主要~程语言
]]>
{
public void breath()
{
Air freshAir = new Air();
freshAir.releasePower();
}
public static void main()
{
Human me = new Human();
while(true)
{
me.breath();
}
}
}
class Air
{
public void releasePower()
{
//do sth.
}
}
{
ArrayList friends = new ArrayList();
public void makeFriend(Human human)
{
friends.add(human);
}
public static void main()
{
Human me = new Human();
while(true)
{
me.makeFriend(mySchool.getStudent());
}
}
}
{
Home myHome;
public void goHome()
{
//在回家的路上
myHome.openDoor();
//看电?br /> }
public static void main()
{
Human me = new Human();
while(true)
{
//上学
//吃饭
me.goHome();
}
}
}
{
Heart myHeart = new Heart();
public static void main()
{
Human me = new Human();
while(true)
{
myHeart.beat();
}
}
}
]]>
]]>
的数目,在NLP中应用比较广泛,如一些评方法中qCQwer,mWer{)Q同时也常用来计你对原文本所作的改动数。编辑距ȝ法是首先由俄国U学家Levenshtein提出的,故又叫Levenshtein Distance?br />Levenshtein Distance法可以看作动态规划。它的思\是从两个字W串的左边开始比?记录已经比较q的子串怼?实际上叫做距?,然后q一步得C一?字符位置时的怼度?用下面的例子: GUMBO和GAMBOL。当到矩阵D[3,3]位置?也就是当比较到GUM和GAM?要从已经比较q的3对子串GU-GAM, GUM-GA和GU-GA之中选一个差别最的来当它的? 所以要从左上到右下构造矩c?br />~辑距离的伪法Q?br />整数 Levenshtein距离(字符 str1[1..lenStr1], 字符 str2[1..lenStr2])
宣告 int d[0..lenStr1, 0..lenStr2]
宣告 int i, j, cost
对于 i {于 ?0 ?lenStr1
d[i, 0] := i
对于 j {于 ?0 ?lenStr2
d[0, j] := j
对于 i {于 ?1 ?lenStr1
对于 j {于 ?1 ?lenStr2
?str1[i] = str2[j] ?cost := 0
否则 cost := 1
d[i, j] := 最?
d[i-1, j ] + 1, // 删除
d[i , j-1] + 1, // 插入
d[i-1, j-1] + cost // 替换
)
q回 d[lenStr1, lenStr2]
double Minimum(double a, double b, double c)
{
double mi;
mi = a;
if (b < mi) {
mi = b;
}
if (c < mi) {
mi = c;
}
return mi;
}
int* GetCellPointer(int *pOrigin, int col, int row, int nCols)
{
return pOrigin + col + (row * (nCols + 1));
}
int GetAt(int *pOrigin, int col, int row, int nCols)
{
int *pCell;
pCell = GetCellPointer (pOrigin, col, row, nCols);
return *pCell;
}
void PutAt(int *pOrigin, int col, int row, int nCols, double x)
{
int *pCell;
pCell = GetCellPointer (pOrigin, col, row, nCols);
*pCell = x;
}
//~辑距离
LD(const char *s, const char *t)
{
int *d; // pointer to matrix
int n; // length of s
int m; // length of t
int i; // iterates through s
int j; // iterates through t
char s_i1; // ith character of s
char s_i2; // ith character of s
char t_j1; // jth character of t
char t_j2; // jth character of t
int *cost; // cost代h矩阵
int result; // result
int cell; // contents of target cell
int above; // contents of cell immediately above
int left; // contents of cell immediately to left
int diag; // contents of cell immediately above and to left
int sz; // number of cells in matrix
// Step 1
n = strlen (s);
m = strlen (t);
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
sz = (n+1) * (m+1) * sizeof (int);
d = (int *) malloc (sz);
cost = (int *) malloc (sz);
// Step 2
for (i = 0; i <= n; i++)
{
PutAt (d, i, 0, n, i);
}
for (j = 0; j <= m; j++)
{
PutAt (d, 0, j, n, j);
}
for (int g=0;g<=m;g++)//把代仯ȝ阵全部初始化为同一个|以后可根据此值判断相应的Ҏ是否被赋q?br /> {
for(int h=0;h<=n;h++)
{
PutAt(cost,h,g,n,2);
}
}
// Step 3
for (i = 1; i <= n; i++)
{
s_i1 = s[i-1];
s_i2 = s[i];
bool sbd=false;
bool tbd=false;
if(s_i1>=' '&&s_i1<='@'||s_i1>='A'&&s_i1<='~' )
{//s为标点符h其他非中文符号和数字
sbd=true;
}
// Step 4
for (j = 1; j <= m; j++)
{
tbd=false;
t_j1 = t[j-1];
t_j2 = t[j];
// Step 5
if(t_j1>=' '&&t_j1<='@'||t_j1>='A'&&t_j1<='~' )
{//t也ؓ标点W号
tbd=true;
}
if(!sbd)
{//s为汉?br /> if(!tbd)
{//t也ؓ汉字
if (s_i1 == t_j1&&s_i2 == t_j2)
{
bool tt=false;
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,0);
tt=true;
}
if(tt)
{//因ؓst全市汉字Q所以把代h矩阵他相ȝ未赋q值的三个D?br /> int temp1=GetAt(cost,i+1,j,n);
if(temp1==2)
{
PutAt(cost,i+1,j,n,0);
}
int temp2=GetAt(cost,i,j+1,n);
if(temp2==2)
{
PutAt(cost,i,j+1,n,0);
}
int temp3=GetAt(cost,i+1,j+1,n);
if(temp3==2)
{
PutAt(cost,i+1,j+1,n,0);
}
}
}
else
{
bool tt=false;
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,1);
tt=true;
}
if(tt)
{
int temp1=GetAt(cost,i+1,j,n);
if(temp1==2)
{
PutAt(cost,i+1,j,n,1);
}
int temp2=GetAt(cost,i,j+1,n);
if(temp2==2)
{
PutAt(cost,i,j+1,n,1);
}
int temp3=GetAt(cost,i+1,j+1,n);
if(temp3==2)
{
PutAt(cost,i+1,j+1,n,1);
}
}
}
}
else
{//t为符?br /> bool tt=false;
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,1);
tt=true;
}
if(tt)
{
int temp1=GetAt(cost,i+1,j,n);
if(temp1==2)
{
PutAt(cost,i+1,j,n,1);
}
}
}
}
else
{//s为符?br /> if(!tbd)
{//t为汉?nbsp;
bool tt=false;
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,1);
tt=true;
}
if(tt)
{
int temp1=GetAt(cost,i,j+1,n);
if(temp1==2)
{
PutAt(cost,i,j+1,n,1);
}
}
}
else
{
if(s_i1==t_j1)
{
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,0);
}
}
else
{
int temp=GetAt(cost,i,j,n);
if(temp==2)
{
PutAt(cost,i,j,n,1);
}
}
}
}
// Step 6
above = GetAt (d,i-1,j, n);
left = GetAt (d,i, j-1, n);
diag = GetAt (d, i-1,j-1, n);
int curcost=GetAt(cost,i,j,n);
cell = Minimum (above + 1, left + 1, diag + curcost);
PutAt (d, i, j, n, cell);
}
}
// Step 7
result = GetAt (d, n, m, n);
free (d);
return result;
}
2Q最长公共子?(LCS)
LCS问题是求两个字W串最长公共子串的问题。解法就是用一个矩阉|记录两个字符
串中所有位|的两个字符之间的匹配情况,若是匚w则ؓ1Q否则ؓ0。然后求出对角线最长的1序列Q其对应的位|就是最长匹配子串的位置.
下面是字W串21232523311324和字W串312123223445的匹配矩阵,前者ؓX方向的,
后者ؓY方向的。不难找刎ͼU色部分是最长的匚w子串。通过查找位置我们得到最长的匚w子串为:21232
0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
但是??的矩阵中找最长的1对角U序列又要花M定的旉。通过改进矩阵的生成方式和讄标记变量Q可以省去这部分旉。下面是新的矩阵生成方式Q?br /> 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
0 1 0 0 0 0 0 0 0 2 1 0 0 0 0
1 0 2 0 1 0 1 0 0 0 0 0 1 0 0
0 2 0 0 0 0 0 0 0 1 1 0 0 0 0
1 0 3 0 1 0 1 0 0 0 0 0 1 0 0
0 0 0 4 0 0 0 2 1 0 0 1 0 0 0
1 0 1 0 5 0 1 0 0 0 0 0 2 0 0
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
0 0 0 2 0 0 0 2 1 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
?字符匚w的时候,我们q不是简单的l相应元素赋?Q而是赋上其左上角元素的值加一。我们用两个标记变量来标记矩阵中值最大的元素的位|,在矩는成的q?E中来判断当前生成的元素的值是不是最大的Q据此来改变标记变量的|那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了?/p>
//最长公共子?br />char* LCS(char*left,char* right){
int lenLeft,lenRight;
lenLeft = strlen(left);
lenRight = strlen(right);
int *c = new int[lenRight];
int start,end,len;
end = len = 0;
for(int i = 0; i < lenLeft; i++){
for(int j = lenRight-1; j >= 0; j--){
if(left[i] == right[j]){
if(i == 0 || j == 0)
c[j] = 1;
else
c[j] = c[j-1]+1;
}
else
c[j] = 0;
if(c[j] > len){
len = c[j];
end = j;
}
}
}
char *p = new char[len+1];
start = end - len + 1;
for(i = start; i <= end; i++)
p[i - start] = right[i];
p[len] = '/0';
return p;
}
3. 余u定理 (向量I间法)
余u定理古老而广泛的数学概念Q在各个学科及实践中都得C大量的应用,q里单的介绍下其在判断两个字W串怼度的应用?br />在余弦定理中基本的公式ؓQ?/p>
假如字符串s1与s2Q比较两个字W串的相似度Qsim(s1,s2)Q假设s1,s2中含有n个不同的字符Q其分别为c1,c2,...cnQ判 断字W串的相似度转换Z个字W串对应的向量v1,v2之间夹角大小的判断,余uD大其向量之间的夹角越,s1与S2的相似度大?br />向量I间法的介l:
?向量I间模型中,文本泛指各种机器可读的记录。用DQDocumentQ表C,特征(TermQ用t表示Q是指出现在文档D中且能够代表该文档内容的?本语a单位Q主要是p或者短语构成,文本可以用特征项集表CZؓD(T1QT2Q?#8230;QTn)Q其中Tk是特征项Q?<=k<=N。例如一文 档中有a、b、c、d四个特征,那么q篇文档可以表CZؓD(aQbQcQd)。对含有n个特征项的文本而言Q通常会给每个特征赋予一定的权重表示?重要E度。即DQD(T1QW1QT2QW2Q?#8230;QTnQWn)Q简CؓDQD(W1QW2Q?#8230;QWn)Q我们把它叫做文本D的向量表C。其中Wk是Tk 的权重,1<=k<=N。在上面那个例子中,假设a、b、c、d的权重分别ؓ30Q?0Q?0Q?0Q那么该文本的向量表CZؓ D(30Q?0Q?0Q?0)。在向量I间模型中,两个文本D1和D2之间的内容相兛_Sim(D1QD2)常用向量之间夹角的余弦DC,公式为:
其中QW1k、W2k分别表示文本D1和D2WK个特征项的权|1<=k<=N。我们可以利用类似的Ҏ来计两个字W串的相兛_?nbsp;
q个法|上没找刎ͼ虽然我写q,但是没什么通用性,׃贴出来。很单的Q有兴趣的可以自己写一个?/p>
(1)所有数据都应该隐藏在所在的cȝ内部?/span>
(2)cȝ使用者必M赖类的共有接口,但类不能依赖它的使用者?/span>
(3)量减少cȝ协议中的消息?/span>
(4)实现所有类都理解的最基本公有接口[例如Q拷贝操?深拷贝和拷?、相{性判断、正输出内宏V从ASCII描述解析{等]?/span>
(5)不要把实现细?例如攄q代码的私有函?攑ֈcȝ公有接口中。如果类的两个方法有一D公׃码,那么可以创Z个防止这些公׃码的U有函数?/span>
(6)不要以用h法用或不感兴趣的东西扰q的公有接口?/span>
(7)cM间应该零耦合Q或者只有导合关系。也卻I一个类要么同另一个类毫无关系Q要么只使用另一个类的公有接口中的操作?/span>
(8)cd该只表示一个关键抽象。包中的所有类对于同一cL质的变化应该是共同闭的。一个变化若对一个包影响Q则对包中的所有类产生影响Q而对其他的包不造成M影响?/span>
(9)把相关的数据和行为集中放|。设计者应当留意那些通过get之类操作从别的对象中获取数据的对象。这U类型的行ؓ暗示着q条l验原则被违反了?/span>
(10)把不相关的信息放在另一个类?也即Q互不沟通的行ؓ)。朝着E_的方向进行依赖?/span>
(11)保你ؓ之徏模的抽象概念是类Q而不只是对象扮演的角艌Ӏ?/span>
(12)在水qx向上可能统一地分布系l功能,也即Q按照设计,层cd当统一地共享工作?/span>
(13)在你的系l中不要创徏全能c?对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。规划一个接口而不是实C个接口?/span>
(14)对公共接口中定义了大量访问方法的cd加小心。大量访问方法意味着相关数据和行为没有集中存放?/span>
(15)对包含太多互不沟通的行ؓ的类多加心。这个问题的另一表现是在你的应用E序中的cȝ公有接口中创Z很多的get和set函数?/span>
(16)在由同用L面交互的面向对象模型构成的应用程序中Q模型不应该依赖于界面,界面则应当依赖于模型?/span>
(17)可能地按照现实世界建模(我们常常Z遵守pȝ功能分布原则、避免全能类原则以及集中攄相关数据和行为的原则而违背这条原? ?/span>
(18)从你的设计中去除不需要的cR一般来_我们会把q个c降U成一个属性?/span>
(19)去除pȝ外的cR系l外的类的特ҎQ抽象地看它们只往pȝ领域发送消息但q不接受pȝ领域内其他类发出的消息?/span>
(20)不要把操作变成类。质疑Q何名字是动词或者派生自动词的类Q特别是只有一个有意义行ؓ的类。考虑一下那个有意义的行为是否应当迁Ud已经存在或者尚未发现的某个cM?/span>
(21)我们在创建应用程序的分析模型时常常引入代理类。在设计阶段Q我们常会发现很多代理没有用的,应当去除?/span>
(22)量减少cȝ协作者的数量。一个类用到的其他类的数目应当尽量少?/span>
(23)量减少cd协作者之间传递的消息的数量?/span>
(24)量减少cd协作者之间的协作量,也即Q减类和协作者之间传递的不同消息的数量?/span>
(25)量减少cȝ扇出Q也卻I减少cd义的消息数和发送的消息数的乘积?/span>
(26)如果cd含另一个类的对象,那么包含cd当给被包含的对象发送消息。也卻I包含关系L意味着使用关系?/span>
(27)cM定义的大多数Ҏ都应当在大多数时间里使用大多数数据成员?/span>
(28)cd含的对象数目不应当超q开发者短期记忆的定w。这个数目常常是6。当cd含多?个数据成员时Q可以把逻辑相关的数据成员划分ؓ一l,然后用一个新的包含类d含这一l成员?/span>
(29)让系l功能在H而深的承体pM垂直分布?/span>
(30)在实现语义约束时Q最好根据类定义来实现。这常常会导致类泛滥成灾Q在q种情况下,U束应当在类的行Z实现Q通常是在构造函C实现Q但不是必须如此?/span>
(31)在类的构造函C实现语义U束Ӟ把约束测试放在构造函数领域所允许的尽量深的包含层ơ中?/span>
(32)U束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第3方对象中?/span>
(33)U束所依赖的语义信息如果很改变,那么最好分布在U束所涉及的各个类中?/span>
(34)cdȝ道它包含什么,但是不能知道谁包含它?/span>
(35)׃n字面范围(也就是被同一个类所包含)的对象相互之间不应当有用关pR?/span>
(36)l承只应被用来ؓ特化层次l构建模?/span>
(37)zcdȝ道基c,基类不应该知道关于它们的zcȝM信息?/span>
(38)基类中的所有数据都应当是私有的Q不要用保护数据。类的设计者永q都不应该把cȝ使用者不需要的东西攑֜公有接口中?/span>
(39)在理ZQ承层ơ体pd当深一点,深好?/span>
(40)在实践中Q承层ơ体pȝ深度不应当超Z个普通h的短期记忆能力。一个广为接受的深度值是6?/span>
(41)所有的抽象c都应当是基cR?/span>
(42)所有的基类都应当是抽象cR?/span>
(43)把数据、行为和/或接口的共性尽可能地放到承层ơ体pȝ高端?/span>
(44)如果两个或更多个cd享公共数?但没有公p?Q那么应当把公共数据攑֜一个类中,每个׃nq个数据的类都包含这个类?/span>
(45)如果两个或更多个cL共同的数据和行ؓ(是Ҏ)Q那么这些类的每一个都应当从一个表CZq些数据和方法的公共基类l承?/span>
(46)如果两个或更多个cd享公共接?指的是消息,而不是方?Q那么只有他们需要被多态地使用Ӟ他们才应当从一个公共基cȝѝ?/span>
(47)对对象类型的昄的分情况分析一般是错误的。在大多数这L情况下,设计者应当用多态?/span>
(48)对属性值的昄的分情况分析常常是错误的。类应当解耦合成一个承层ơ结构,每个属性值都被变换成一个派生类?/span>
(49)不要通过l承关系来ؓcȝ动态语义徏模。试囄静态语义关pL为动态语义徏模会D在运行时切换cd?/span>
(50)不要把类的对象变成派生类。对M只有一个实例的zc都要多加小心?/span>
(51)如果你觉得需要在q行时刻创徏新的c,那么退后一步以认清你要创徏的是对象。现在,把这些对象概括成一个类?/span>
(52)在派生类中用I方?也就是什么也不做的方?来覆写基cM的方法应当是非法的?/span>
(53)不要把可选包含同对承的需要相h。把可选包含徏模成l承会带来泛滥成灄cR?/span>
(54)在创建承层ơ时Q试着创徏可复用的框架Q而不是可复用的组件?/span>
(55)如果你在设计中用了多重l承Q先假设你犯了错误。如果没犯错误,你需要设法证明?/span>
(56)只要在面向对象设计中用到了承,问自׃个问题:(1)zcL否是它承的那个东西的一个特D类型?(2)基类是不是派生类的一部分Q?/span>
(57)如果你在一个面向对象设计中发现了多重承关p,保没有哪个基类实际上是另一个基cȝzcR?/span>
(58)在面向对象设计中如果你需要在包含关系和关联关p间作出选择Q请选择包含关系?/span>
(59)不要把全局数据或全局函数用于cȝ对象的薄记工作。应当用类变量或类Ҏ?/span>
(60)面向对象设计者不应当让物理设计准则来破坏他们的逻辑设计。但是,在对逻辑设计作出决策的过E中我们l常用到物理设计准则?/span>
(61)不要l开公共接口M改对象的状态?/span>
原文地址Q?a style="color: #0066ff; text-decoration: none; ">http://coolshell.cn/articles/4119.html
因ؓ之前收藏的地址找不CQ所以重新发一?/p>
昨天写了一?a title="如何学好C语言" target="_blank" style="color: #0066ff; text-decoration: none; ">如何学好C语言Q就有h回复问我如何学好C++Q所以,我把我个人的一些学习经验写在这里,希望对大家有用。首先,因ؓ如何学好C语言中谈C法和系l,所以这里就只谈C++语言?/p>
希望没有吓到大家QƈƢ迎大家补充?/p>
—————更新 2011/03/30 19:20————
更新几个观点Q?/p>
如何判断一D늨序是由C ~译E序q是由C++~译E序~译的?
{案Q?nbsp;
如何打印出当前源文g的文件名以及源文件的当前行号Q?nbsp;
{案Q?nbsp;
cout << __FILE__ ;
cout<<__LINE__ ;
__FILE__和__LINE__是系l预定义宏,q种宏ƈ不是在某个文件中定义的,而是q译器定义的?/p>
main d数执行完毕后Q是否可能会再执行一D代码,l出说明Q?nbsp;
{案Q可以,可以用_onexit 注册一个函敎ͼ它会在main 之后执行?/p>
The _onexit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to _onexit cannot take parameters.
cL员函数的重蝲、覆盖和隐藏区别Q?nbsp;
{案Q?nbsp;
a.成员函数被重载的特征Q?nbsp;
Q?Q相同的范围Q在同一个类中)Q?nbsp;
Q?Q函数名字相同;
Q?Q参C同;
Q?Qvirtual 关键字可有可无?/p>
Q?Qconst的区?nbsp;
b.覆盖是指zcd数覆盖基cd敎ͼ特征是:
Q?Q不同的范围Q分别位于派生类与基c)Q?nbsp;
Q?Q函数名字相同;
Q?Q参数相同;
Q?Q基cd数必Lvirtual 关键字?nbsp;
c.“隐藏”是指zcȝ函数屏蔽了与其同名的基类函数Q规则如下:
Q?Q如果派生类的函C基类的函数同名,但是参数不同。此Ӟ不论有无virtual关键字,基类的函数将被隐藏(注意别与重蝲hQ?nbsp;
Q?Q如果派生类的函C基类的函数同名,q且参数也相同,但是基类函数没有virtual 关键字。此Ӟ基类的函数被隐藏Q注意别与覆盖淆)
(1)已知W二l?/div> (2)已知W一l?/div> (3)已知W一l_一ơ分配内?保证内存的连l? (4)两维都未?/div> (5)两维都未知,一ơ分配内?保证内存的连l? 2.C++动态分配二l数l?/strong> (1)已知W二l?/div> (2)已知W一l?/div> (3)已知W一l_一ơ分配内?保证内存的连l? (4)两维都未?/div> (5)两维都未知,一ơ分配内?保证内存的连l? 多说一句:new和delete要注意配对用,x多少个new有多少个deleteQ这h可以避免内存泄漏Q?/span> 3.静态二l数l作为函数参C?/strong> 如果采用上述几种Ҏ动态分配二l数l,那么对应的数据cd作ؓ函数参数可以了。这里讨论静态二l数l作为函数参C递,x照以下的调用方式Q?/div> int a[2][3]; func(a); C语言中将静态二l数l作为参C递比较麻烦,一般需要指明第二维的长度,如果不给定第二维长度Q则只能先将其作Zl指针传递,然后利用二维数组的线性存储特性,在函C内{化ؓҎ定元素的讉K?/div> 首先写好试代码Q以验证参数传递的正确性: (1)l定W二l长?/div> (2)不给定第二维长度 注意Q用该函数旉要将二维数组首地址强制转换Zl指针,即func((int*)a); |