C++學習隨筆1

頂層const和底層const的區別:
頂層const表示任意的對象是常量
底層const與指針和引用等複合類型的基本類型部分有關
在執行拷貝操作時,頂層const和底層const區別明顯。頂層const不受影響,底層const限制 拷入和拷出的對象必須具有相同的底層const資格,或者兩個對象的數據類型必須能夠轉換。
一般來說,非常量可以轉換成常量,反之則不行。

const int v2=0;			//頂層,整型常量
int v1 = v2;
int *p1=&v1, &r1=v1;
const int *p2=&v2;		// 底層,所指的對象是常量
const *const p3=&i,     // 頂層,整型常量指針 
const *const &r2=v2;	// 底層 所引用的對象是常量

auto 和 decltype的區別主要有三個方面:
第一,auto類型說明符用編譯器計算變量的初始值來推斷其類型,而decltype雖然也讓編譯器分析表達式並得到它的類型,但是不實際計算表達式的值。
第二,編譯器推斷出來的auto類型有時候和初始值的類型並不完全一樣,編譯器會適當地改變結果類型使其更符合初始化規則,decltype會保留變量的頂層const。
第三,與auto不同,decltype的結果類型與表達式形式密切相關,如果變量名加上一對括號,則得到的類型與不加括號時會有不同。如果decltype使用的是一個不加括號的變量,則得到的結果就是該變量的類型;如果給變量加上一層或多層括號,則編譯器將推斷得到應用類型。

int a =3;
decltype(a) c=a;   		// int c=a
decltype((a)) d=a;		// int &c=a

面向對象程序設計

封裝、繼承、多態
封裝是指保護類的成員不被隨意訪問的能力。通過把類的實現細節設置爲private,就能完成類的封裝。封裝實現了類的接口和實現的分離。
優點:
一、確保用戶代碼不會無意間破壞封裝對象的狀態;
二、被封裝的類的具體實現細節可以隨時改變,而無須調整用戶級別的代碼;

虛函數、虛成員
在類中被聲明爲virtual的成員,基類希望這種成員在派生類中重新定義。
除了構造函數外,任意非static成員都可以爲虛成員

protected與private的區別
protected爲受保護的訪問標號,protected成員可以被該類的成員、友元和派生類成員(非友元)訪問,而不可以被該類型的普通用戶訪問。
private成員只能被基類成員和友元訪問,派生類不能訪問。

靜態類型和動態類型
靜態類型在編譯時就已經確定,它是變量聲明時的類型或表達式生成的類型;
動態類型是變量或表達式表示的內存中的對象的類型,動態類型直到運行時才能知道。
如果一個變量非指針也非引用,則它的靜態類型和動態類型永遠一致。

Quote *pQuote = new Bulk_quote;  // 指針pQuote的靜態類型時Quote,在編譯時就已經確定了。但是它的動態類型時Bulk_quote,直到運行時才能知道它指向的是基類還是派生類。

友元
友元爲類的非成員接口函數提供了訪問其私有成員的能力。
當非成員函數確實需要訪問類的私有成員時,可以把它聲明成改類的友元。此時,友元可以“工作在類的內部”,像類的成員一樣訪問類的所有數據和函數。但是一旦使用不慎,就有可能破壞類的封裝性。

把類的成員函數定義成內聯函數
1.直接把函數定義在類的內部
2.把函數定義放在類的外部,並且在定義之前顯式地指定inline。

// 隱式內聯
class Sales_data
{
public:
	double avg_price() const{
		...
	}
}

// 顯式內聯
class Sales_data
{
	double avg_price()	const;
}
inline double Sales_data::avg_price()	const
{
	...   
}

順序容器

與vector和deque不同,list的迭代器不支持<運算,只支持遞增、遞減、==以及!=運算。原因在於vector和deque將元素在內存中連續保存,而list則是將元素以鏈表方式存儲

  • vector
    capacity和size有何區別:capacity返回已經爲vector分配了多大內存空間(單位是元素大小),也就是在不分配新空間的情況下,容器可以保存多少個元素。而size則返回容器當前已經保存了多少個元素。
  • deque
  • list

範型算法

頭文件:algorithm
關鍵:範型算法不會直接調用容器的操作,而是通過迭代器來訪問、修改、移動元素。不能直接向/從容器添加、刪除元素,無法改變容器大小。對於copy算法的第三個參數使用back_inserter()函數;

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	vector<int> vi={1,2,3,4,2,2,7};
	int val;
	count << “請輸入要搜索的整數:”;
	con >> val;

	cout << “序列中包含” << count(vi.begin(), vi.end(), Val) <<  “個”<<val;
	
	return 0;
}

算法不改變容器大小的原因
將算法與數據結構分離,重要的技術手段就是使用迭代器作爲兩者都的橋樑。算法從不操作具體的容器,從而也就不存在與特定容器綁定,不適用於其他容器的問題。爲實現通用性,算法根本就不知道容器的存在。算法訪問數據的唯一通道是迭代器。
是否改變容器大小,完全是迭代器的選擇和責任。

三種插入迭代器的區別

  • front_inserter
    調用push_front, 總是插入到容器首元素之前
  • inserter
    調用insert,插入到給定位置之前(作爲inserter的第二個參數傳遞給它)
  • back_inserter
    調用push_back,插入到容器尾元素之後
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章