被問倒了
看來我真的很嫩很嫩...
不過還是要學習一下
===================================================================================
What is Memory leak?
以下是wikipedia的原文解釋
In computer science, a memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.
This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws.
簡單的說,就是我們所謂的記憶體垃圾,C/C++中並無像Java或C#有垃圾收集器,所以指標的亂用可能會造成記憶體裂縫。
而所謂的記憶體垃圾,就是我們在程式執行間所分配出來使用的記憶體,在使用完後,沒有有效的清除,或者清除了以後,卻仍有指標索引的,很容易造成bug出現。所以良好的寫程式習慣是一定要的,使用指標完要確實delete掉,且指標要轉成NULL。
=====================================================================================
描述 Macro、inline function、function的不同
Macro 巨集
在編譯時,程式碼中有呼叫巨集的部份,將會被原始巨集所取代,就是複製一份去覆蓋的地方,好處是程式執行不用跳離,壞處則是增加程式碼容量。
先說function
function函式
編譯時,呼叫到函式的地方會變成jump指令,jump到函式編譯的位址,在使用時,發現要進入函式時,會先要求OS配置記憶體,載入好函式指令後,再進入執行。優點是主程式不肥,需要用時再載入,加快程式準備時間,但缺點是一但要使用函式,會花時間去載入。
inline function
行內函式
介於macro與function之間,以下是wiki的解釋
In computer science, an inline function is a programming language construct used to suggest to a compiler that a particular function be subjected to in-line expansion; that is, it suggests that the compiler insert the complete body of the function in every context where that function is used.
簡單的說,寫上inline的function,compiler會去判定適不適合展開,如果適合,會像Macro一樣在程式碼內展開,如果不適合,就會像一般的function一樣使用jump執行。而展不展開是根據compiler決定,不同的compiler會有不同的作法。
=====================================================================================
Virtual function虛擬函式
因為太長了,所以直接貼網路上找到的
來源
虛擬函式(Virtual function)
當我們使用繼承的方法來使用其他類別的函式時,會出現一個問題,即別的類別的函式,
並不完全適合我們的需求,因此,便有了" 虛擬函式"(virtual function)的設計。透過虛擬函式,
我們可以更改函式成為我們所要的function。
虛擬函式的宣告
在函式的前頭加上" virtual ",即宣告此函式為虛擬函式。
// The general syntax for declaring virtual functions is as follows:
class className1
{
// member functions
virtual returnType functionName();
};
class className2 :public className1
{
// member functions
virtual returnType functionName();
};
虛擬函式的特性:
虛擬函式是一種動態的函式,此類函式必須要等到函式執行時,才決定要執行什麼程
式。
見下面的範例
The following example shows how virtual functions can successfully implement polymorphic behavior in the cA and cB classes
#include
class cA
{
public:
virtual double A(double x) {return x * x ; }
double B(double x) {return A(x)/2;}
};
class cB : public cA
{
public:
virtual double A(double x) {return x * x * x ; }
};
int main( )
{
cB aB;
cout << aB.B(3) << "\n";
return 0;
}
範例解說:
class cA
{
public:
virtual double A(double x) {return x * x ; }
double B(double x) {return A(x)/2;}
};
class cB : public cA
{
public:
virtual double A(double x) {return x * x * x ; }
};
宣告虛擬函式
我們在分別在類別cA中及類別cB中宣告一個虛擬函式 :
virtual double A(oduble x) {return x*x ; }
和
virtual double A(oduble x) {return x*x*x; }
這二種函式的運算並不相同,而這二個宣告為虛擬函式的部分,必須要等到函式
執行才決定要傳回 x*x 或是 x*x*x .
類別cB繼承類別cA, class cB: public cA
int main( )
{
cB aB;
cout << aB.B(3) << "\n";
return 0;
}
在主程式的地方,我們宣告一個物件aB,其類別為cB : cB aB
接著,我們做aB的B函式的運算,x值為3, aB.B(3)
class cB : public cA
{
public:
virtual double A(double x) {return x * x * x ; }
};在cB中並沒有函式B,所以我們回到上一層繼承的類別cA中找:
class cA
{
public:
virtual double A(double x) {return x * x ; }
double B( double x ) {return A(x)/2;}
};找到函式B,然後將x=3代入,這時,我們可以發現,其傳回函式為:return A(x)/2
,函式A被宣告為 virtual。
被宣告為 virtual的函式,必須要等到函式執行至此的時候才決定要執行什麼;我
們回到cB中可以發現,cB中也有函式A。
compiler這時候要如何決定用cA還是cB的函式呢?
因為我們要計算的是cB.B(3),因此,compiler一但發現繼承而來的類別cA中的函式A被
宣告為virtual,compiler便不會直接使用cA的A函式,它會回到cB中看看cB中是否有A函式:
class cB : public cA
{
public:
virtual double A(oduble x) {return x * x * x ; }
};結果找到了! 在cB有一個虛擬函式 A
compiler此時便不用cA中而使用cB中的函式A了。
在設計類別(Class)的時候,透過虛擬函式(virtual function)的設計,可以讓程式變得更有彈性;
尤其是當我們所設計的類別在未來有被其他類別繼承的可能,而函式有被修改的可能及
必要時,最好能夠設計為virtual function,以提供其他類別能夠修改使用函式。
====================================================================================
const用法
具體定義:常量、不可變動,常用在防止數值被修改。下面有一些用法
int XXX(const int array[], int num)
在XXX函式中,array[]只可以被取值,不可填值,也就是說,只可出現 = array[],不可出現array[]=的形式。
另一些用法說明
const char ch = 'a';
//ch為'a',且不可變動。
const int a[5] = {1, 2, 3, 4, 5};
//a[]陣列內值固定,不可變動。所以使用時要事先給定義值。
const int *p = b;
//b是陣列的地址,p是指向常量的指針,b陣列值不可經由p來更改,例如:
// *p = 10; --Error
// *(p + 2) = 1; --Error
// b[0]=0; OK
int * const p = b;
//b是陣列的地址,p是常量型指針,p的位址值不可改變,但所指的值可以變,如:
// *p = 0; OK
// *(p+1) = 0; OK
// p++; Error
// b[0]=0; OK
const int * const p = b;
//b是陣列的地址,p是常量型指針,且p指向常量。所以p本身不能改,也不可經過p更改b的值。
// *p = 0; Error
// *(p+1) = 0; Error
// p++; Error
// b[0]=0; OK
例如A本身沒定義const,利用A更改不會出錯,如果B以const連到A,則不可藉由B來更改A的值,但A可以更改自己的值。
如果A本身定為const,則不可利用A更改內值,且任何連到A的B,都不可以更改A值。
by Keng-li.Lin
沒有留言:
張貼留言