這裏記錄一下在找工做前的複習過程當中那些讓我懷疑我是否是真的學過計算機的知識點。。html
cout << boolalpha << (1 == 2);
輸出false
參考連接:http://www.cnblogs.com/devymex/archive/2010/09/06/1818754.html數組
const
在*
的左側,如 const int *a
或int const *a
,不能改變指針a
指向的內容的值const
在*
的右側,如 int* const a
,指針a
自己爲常量,不能改變a
的指向ide
我的以爲把const
放在類型符號後邊意義更明確一些。。函數
在類中,修飾爲mutable
的成員變量能夠被修飾爲const
的成員函數修改優化
class A { public: mutable int a; void set_a(int n) const { a = n; } };
sizeof()結果由編譯時肯定,()內代碼不被執行ui
int a = 0; sizeof(a = 1);
a
的值不會被改變this
注意,引用也是要佔用內存空間的,內容是被引用的變量的地址,同指針同樣spa
struct st1 { int a; int &b; st1(int n) : a(n), b(a) {} }; struct st2 { int a; int *b; st2(int n) : a(n), b(&a) {} }; st1 s1(10); st2 *ps2 = reinterpret_cast<st2*>(&s1); cout << *(ps2->b); // 10
參考連接:http://blog.csdn.net/thisispan/article/details/7456169.net
int *a[10];//包含十個元素的數組,數組元素是整型指針 int *(a[10]);//同上 int (*a)[10];//指向具備十個整型元素的數組的指針 int (*a)();//指向無參數且返回整型的函數的指針 int (*a[10])();//包含十個元素的數組,數組元素是指向無參數且返回整型的函數的指針 int (**a)[10];//指向一維數組指針的指針,數組具備十個整型元素 int *(*a)[10];//指向一維數組的指針,數組具備十個整型指針元素 int (*(*a)(int))();//指向具備一個整型參數且返回函數指針的函數的指針,返回的函數指針指向無參數且返回整型的函數
int a[5] = {1, 2, 3, 4, 5}; int *p = (int*)(&a + 1); cout << (int)*(p - 1);
輸出爲5
數組名a
是指向數組第一個元素的指針,&a
是指向數組的指針,雖然兩個指向同一個地址,可是&a + 1
其實是將指針向後移動了sizeof(a),也就是20個字節,與a + 1
移動一個字節不一樣
在這裏p
相似於二維數組線程
this
指針其實是類成員函數的第一個參數,由編譯器自動添加,經過寄存器傳遞,整個生命週期同函數參數一致
刪除vector
等連續空間的容器元素後,相應迭代器會失效
struct
與class
除了默認訪問控制不一樣之外,其餘徹底相同。struct
默認訪問控制是public
,class
默認訪問控制是private
除開父類構造函數,成員變量初始化按照成員變量在類中申明的順序執行,與初始化列表順序無關
除了虛函數和靜態成員函數,其餘函數能夠是內聯的,包括構造函數和析構函數。
事實上,若是成員函數在類申明中定義,那麼默認是內聯的。類申明外定義的函數能夠用inline
修飾爲內聯的。但須要注意的是,內聯函數是內部連接的,只能在本文件內被調用。
//A.h class A { public: A() { cout << "A()" << endl; } inline virtual ~A() { cout << "~A()" << endl; } inline void func1() { cout << "func1" << endl; } void func2(); }; //A.cc inline void A::func2() { cout << "func2" << endl; } //main.cc A *a = new A; a->func1(); a->func2();// 編譯失敗 delete a;
class A { public: int m; A(int n) : m(n) {} A(float n) : m(n * 2) {} }; A a = 10; // a.m == 10 A a = 10.0;// a.m == 20
單個參數的函數若是不添加explicit,會發生隱式的類型轉換
私有繼承與保護繼承的派生類不能稱爲子類,由於派生類並不能完成父類能作的全部事情
參考連接:http://www.oschina.net/translate/cpp-virtual-inheritance
將構造函數申明爲private或純虛類(抽象類)
將析構函數申明爲private
重載new運算符爲private
將複製構造函數和賦值函數聲明爲private,或者聲明爲 = delete
加final關鍵字
其餘方法:http://blog.chinaunix.net/uid-26983585-id-4373697.html
static_cast和C語言裏的強制類型轉換類似,不過編譯時會作類型檢查,只有相關的類型才能轉換,不然編譯錯誤
dynamic_cast在程序運行時根據對象的虛表進行向上或者向下轉換。轉換指針失敗時,返回nullptr,轉換引用失敗時,拋出異常
然而Google並不建議使用dynamic_cast,參考:http://www.zhihu.com/question/22445339
const_cast去除對象的只讀屬性
reinterpret_cast不作二進制轉換,僅僅是從新解釋二進制塊,經常用在偏底層的操做上,可移植性稍弱
class A { public: static int m; int n; void func1() { cout << this << ' ' << m << endl; } void func2() { cout << this << ' ' << n << endl; } static void func3() { cout << m << endl; } }; int A::m = 10; A *a = 0; a->func1();// 0 10 a->func2();// crash a->func3();// 10 A::func3();// 10
若是對象指針指向錯誤的地址,對象成員函數仍然能夠被調用,可是不能訪問非靜態成員變量。這裏同時也將靜態成員函數拿出來比較。
想想,假如成員函數是虛函數,結果還會同樣麼?
struct A { int a:1; int b:2; int c:3; }; cout << sizeof(A);// 4
參考連接:http://www.cnblogs.com/bigrabbit/archive/2012/09/20/2695543.html
模塊
函數
類
起到的做用有什麼異同
volatile關鍵字告訴編譯器不要優化被它修飾的變量,這個變量可能在編譯器控制範圍外發生改變,好比中斷或者其餘線程
注意下面這個例子
int func(volatile int *p) { // return (*p) * (*p); // wrong int temp = *p; return temp * temp; }
不一樣類型的變量參與混合運算時,全部變量將會轉換爲同一類型,爲了避免丟失精度,老是轉換爲長度更長的變量
在32位機器上,char,short老是轉換爲int,float老是轉換爲double
通常狀況下,不用關注轉換的問題,可是考慮下面一個例子:
signed char a = 0xe0; unsigned int b = a; cout << int(a) << ' ' << b;
結果 -32 4294967264
由於在a賦值給b時,a要提高爲32位的unsigned int型。然而a是負數,在提高長度時高位將用1
來補全,因而a被提高爲0xffffffe0
。賦值後,b的值爲0xffffffe0
,因此做爲無符號整型輸出爲4294967264
const成員變量必須在構造函數初始化列表中被初始化。
class A { public: const int m; A(int n) : m(n) {} };
static const成員變量能夠在聲明時初始化
class A { public: static const int m = 0; A(int n) {} };
static成員變量不能在聲明時初始化,也不能在構造函數初始化列表中初始化,只能在類外申明並初始化
C++ 11已經支持非靜態(static const例外)成員變量聲明時初始化,自定義類型不能執行帶參數的構造函數
C和C++程序中,函數的調用有多種方式,能夠經過在函數聲明時加上__stdcall
,__cdecl
,__fastcall
來顯式指定
不一樣的函數調用方式體如今參數傳遞方式,編譯後函數命名方式,函數返回時棧清理方式的不一樣。
參考連接:http://www.cnblogs.com/zhangchaoyang/articles/2725189.html
簡單的說,具備變長參數的函數在調用時(__cdecl方式),編譯器按正常的方式將參數從右到左入棧,函數內部再經過指針根據參數類型依次從棧中將參數取出
以printf("%c,%d", 'A', 10);
舉慄
由於參數從右到左進棧且棧是從高地址到低地址生長的,因此此時內存是這樣的:
低地址<<| 4 byte | 1 byte | 4 byte |>>高地址 |"%c,%d"的地址| 'A' | 10 |
首先printf
函數的第一個參數不是變長參數,這裏咱們假設這個參數叫str
,它是指向"%c,%d"
的指針。有了str
,咱們天然就知道了變長參數的起始地址是&str+1
,而後再根據"%c,%d"
,咱們知道了變長參數有兩個並且類型分別爲char
和int
,因而咱們就能夠依次獲得這兩個變量辣
參考連接:http://www.cnblogs.com/chinazhangjie/archive/2012/08/18/2645475.html
經過const_cast能夠去除read-only屬性,可是編譯時編譯器仍將使用到const變量的地方直接替換爲初始化的那個值,相似於宏
int const a = 1; int *p = const_cast<int*>(&a); *p = 2; cout << a << " " << *p; // 輸出: 1 2
加override
,貌似又是C++ 11的關鍵字
class A { public: virtual void func(int n); } class B : A { public: virtual void func(int n); // 不要這樣,若是參數寫錯了,至關於聲明瞭重載函數 void func(int n); // 同上 void func(int n) override; // 強制重寫基類函數,若是參數或返回值與基類虛函數不一致,編譯器報錯 }
未完......