C++日記——Day55:容器分類,array、vector容器精解

容器分類:(三大類)

1、順序容器:放進去在哪裏元素就排在哪裏。如:arrary、vector、deque、list、forward_list;

2、關聯容器:元素是 鍵/值 對,特別適合做查找。你能控制插入內容,但是一般來講你不能控制插入位置。如:hash_set、hash_map、hash_multiset、hash_multimap;

3、無序容器:元素位置不重要,重要的是這個元素在容器中。無序容器也屬於一種關聯容器。

unordered_set、unordered_mutiset、unordered_map、unordered_multimap;

哈希表:藍色——》籃子

官方有一句話:C++11標準並沒有規定任何容器必須使用特定的實現手段。

 

容器的說明和應用實例:

1、arrary:是個順序容器,其實是個數組,內存空間是連續的,大小是固定的;你剛申請的時候多大,他就是多大,不能在改變它的大小

namespace nmsp1 {

	void func() {
		array<string, 5> mystring{ "I","Love1Love2Love3Love4Love5Love6Love7","China" };
		cout << "myString.size() = " << mystring.size() << endl;
		mystring[0] = "It is very long~~~~~~~~~~~~~~~~~long~~~~~~~~~~~~~~long";
		mystring[4] = "It is very long~~~~~~~~~~~~~~~~~long~~~~~~~~~~~~~~long";
		cout << "sizeof(string) = " << sizeof(string) << endl;
		for (size_t i = 0; i < mystring.size(); ++i) {
			const char *p = mystring[i].c_str();
			cout << "-------------------begin----------------------" << endl;
			cout << "數組元素值= " << p << endl;
			printf("對象地址:%p\n", &mystring[i]);
			printf("對象指向的字符串地址:%p\n", p);
			cout << "------------------end--------------------------" << endl;
		}
		const char *p1 = "This is my life, This is my life";
		const char *p2 = "This is my life, This is my life";

		printf("p1字符串地址:%p\n", p1);
		printf("p2字符串地址:%p\n", p2);
	}
}

int main() {
	nmsp1::func();
	return 0;
}

 由上可知,字符串的存儲形式如下,當存儲的字符串大於string的存儲空間時,編譯器會在外邊找一塊空間用來存放這個字符串。

 p1、p2指向的內存地址相同。

 

2、vector

a、往後邊增加元素和刪除元素很快。

b、往中間插入元素可能導致很多元素析構,重新構造,效率會非常低。

c、查找速度應該不會太快。

namespace nmsp2 {
	class A {
	public:
		int m_i;
		A(int tmpv) :m_i(tmpv) {
			cout << "A::A()構造函數執行" << endl;
		}

		A(const A &tmpa) :m_i(tmpa.m_i) {
			cout << "A::A()拷貝構造函數執行" << endl;
		}

		~A() {
			cout << "A::~A()析構函數執行" << endl;
		}

	};

	void func() {
		vector<A> myveca;
		for (int i = 0; i < 1; ++i) {
			cout << "---------------------begin-----------------------" << endl;
			myveca.push_back(A(i));
			cout << "----------------------end------------------------" << endl;
		}
	}
}


int main() {
	nmsp2::func();
	return 0;
}

 

namespace nmsp2 {
	class A {
	public:
		int m_i;
		A(int tmpv) :m_i(tmpv) {
			cout << "A::A()構造函數執行" << endl;
		}

		A(const A &tmpa) :m_i(tmpa.m_i) {
			cout << "A::A()拷貝構造函數執行" << endl;
		}

		~A() {
			cout << "A::~A()析構函數執行" << endl;
		}

	};

	void func() {
		vector<A> myveca;
		for (int i = 0; i < 5; ++i) {
			cout << "---------------------begin-----------------------" << endl;
			myveca.push_back(A(i));
			cout << "----------------------end------------------------" << endl;
		}
	}
}


int main() {
	nmsp2::func();
	return 0;
}

vector容器內存空間是也是挨着的,vector容器有一個“空間”的概念。

過程大概是這樣的:首先編譯器找一個能存放一個元素的空間存入該元素,在此插入元素時空間不夠了,因爲要要求存儲空間連續所以,編譯器要釋放掉現有的內存,重新找一塊能容納兩個元素的空間,放入這兩個元素(一個先構造在拷貝,一個直接拷貝),過程以此類推。

容器裏有多少個元素可以用size()來看,而容器有多少空間可以用 capacity()來看;

capacity()一定不會小於size();

namespace nmsp2 {
	class A {
	public:
		int m_i;
		A(int tmpv) :m_i(tmpv) {
			cout << "A::A()構造函數執行" << endl;
		}

		A(const A &tmpa) :m_i(tmpa.m_i) {
			cout << "A::A()拷貝構造函數執行" << endl;
		}

		~A() {
			cout << "A::~A()析構函數執行" << endl;
		}

	};

	void func() {
		vector<A> myveca;
		for (int i = 0; i < 6; ++i) {
			cout << "---------------------begin-----------------------" << endl;
			cout << "容器插入元素之前size= " << myveca.size() << endl;
			cout << "容器插入元素之前capacity= " << myveca.capacity() << endl;
			myveca.push_back(A(i));
			cout << "容器插入元素之後size= " << myveca.size() << endl;
			cout << "容器插入元素之後capacity= " << myveca.capacity() << endl;
			cout << "----------------------end------------------------" << endl;
		}
	}
}


int main() {
	nmsp2::func();
	return 0;
}

reserve(int size)用於預留空間,前提是你知道這個容器最多會容納多少個元素;可以大大提高程序效率。

vector<A> myveca;
myveca.reserve(10);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章