1.接口和抽象類的區別
- 接口是對動作的抽象;抽象類是對根源的抽象。
- 抽象類表示這個對象是什麼;接口表示的是,這個對象能做真麼。
- 一個類一般只能繼承一個抽象類;但是可以實現多個接口。
2.sizeof
class A
{
};
class B
{
public:
B(){}
};
class C
{
public:
virtual void fun(){};
};
class D
{
public:
virtual void fun() = 0;
};
- sizeof(A) = 1 :因爲我們聲明類類型的實例的時候,必須在內存中佔有一定的空間,否則無法使用這些實例。
- sizeof(B) = 1 :因爲調用構造函數與析構函數只用知道函數地址即可。
- sizeof(C) = 4 :虛函數需要一個指向虛表的指針,而一個指針在32位機器上是4字節,在64爲機器上是8字節。
- sizeof(D) = 4 :同上
3.main函數執行以前及以後,分別還會執行什麼。
1)執行之前:
- 設置棧指針
- 初始化static靜態與全局變量,即data段的內容
- 將未初始化的全局變量,static變量賦值:數值型賦值爲0,bool賦值爲false,指針爲NULL,即bss段的內容
- 將main函數的參數,argc, argv傳遞給main函數。
2)執行之後:
- 全局對象的析構函數
- 在main函數中用ateixt()註冊的終止處理程序。
4.malloc與new的區別
1)new是c++中的操作符;malloc是c中的一個函數
2)new不只會分配內存,而且會調用類的構造函數,同理delete會調用類的析構函數;而malloc則只是分配內存,不會進行初始化類成員的工作,同樣free也不會調用析構函數。
3)不要用malloc/free來完成動態對象的內存管理,因爲他們並沒有調用構造/析構函數。
4)如果用free釋放new 出來的對象,這個對象有可能因爲無法執行析構函數而導致程序出錯。如果用delete釋放malloc申請的動態內存,原則上是不會錯的,但是容易引起誤會。
一篇實現malloc的文章
new與malloc的區別,以及內存分配淺析
new的注意一點:
int *ia = new int; //ia所指向的數值是未知的
int *ib = new int(); //ib所指向的數值是0
5.c++ 線程安全的單例模式
#include <thread>
#include <mutex>
class Lock
{
private:
std::mutex *cs; //臨界資源
public:
Lock(std::mutex *mt):cs(mt)
{
cs->lock();
}
~Lock()
{
cs->unlock();
}
};
class single
{
private:
static single *pSingle;
static std::mutex cs; //臨界資源
class Garbo
{
public:
~Garbo()
{
if(single::pSingle)
delete single::pSingle;
}
};
static Garbo garbo;
public:
static single *Instance()
};
single *single::pSingle = nullptr;
single * single::Instance()
{
if(pSingle == nullptr)
{
Lock lock(&cs); //這裏聲明瞭一個Lock類型的局部變量,這樣
//在退出他的作用域之後就可以調用他的析構
//函數來對cs進行unlock;
if(pSingle == nullptr)
{
pSingle = new single();
return pSingle;
}
}
return pSingle;
}
6.static變量
static變量分爲靜態的全局變量與靜態的局部變量。
他們之間的區別在靜態的全局變量是一個全局的變量,可以被其他函數訪問。而靜態的局部變量只是一個局部變量,不能被其他函數訪問。
第二:靜態全局變量是在main函數之前被初始化的。而靜態的局部變量是在執行到這個函數時才被初始化。
但是他們都存儲在bss段或者data段。
常量存儲區
char *str1 = "ABCD";
char *str2 = "ABCD";
/* 這裏str1 == str2,因爲ABCD存儲在常量存儲區,str1與str2都指向這一塊區域。 */