最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++?string類擴(kuò)展知識(shí)全解析

 更新時(shí)間:2026年05月25日 09:45:45   作者:王璐WL  
這段文章詳細(xì)解釋了C++中`String`類的模擬實(shí)現(xiàn),重點(diǎn)討論了淺拷貝、深拷貝及寫時(shí)拷貝的概念與實(shí)現(xiàn),強(qiáng)調(diào)了資源管理的重要性,并對(duì)比了不同編譯器下(如Visual?Studio和g++)下`string`結(jié)構(gòu)的差異,最后補(bǔ)充了相關(guān)接口設(shè)計(jì)和擴(kuò)展閱讀建議

1.string類的模擬實(shí)現(xiàn)


說明:上述String類沒有顯式定義其拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載,此時(shí)編譯器會(huì)合成默認(rèn)的,當(dāng)用s1構(gòu)造s2時(shí),編譯器會(huì)調(diào)用默認(rèn)的拷貝構(gòu)造。最終導(dǎo)致的問題是,s1、s2共用同一塊內(nèi)存空間,在釋放時(shí)同一塊空間被釋放多次而引起程序崩潰,這種拷貝方式,稱為淺拷貝。

1.1 淺拷貝

淺拷貝:也稱位拷貝,編譯器只是將對(duì)象中的值拷貝過來。如果對(duì)象中管理資源,最后就會(huì)導(dǎo)致多個(gè)對(duì)象共享同一份資源,當(dāng)一個(gè)對(duì)象銷毀時(shí)就會(huì)將該資源釋放掉,而此時(shí)另一些對(duì)象不知道該資源已經(jīng)被釋放,以為還有效,所以當(dāng)繼續(xù)對(duì)資源進(jìn)項(xiàng)操作時(shí),就會(huì)發(fā)生發(fā)生了訪問違規(guī)。

就像一個(gè)家庭中有兩個(gè)孩子,但父母只買了一份玩具,兩個(gè)孩子愿意一塊玩,則萬事大吉,萬一不想分享就你爭我奪,玩具損壞。
可以采用深拷貝解決淺拷貝問題,即:每個(gè)對(duì)象都有一份獨(dú)立的資源,不和其他對(duì)象共享。父母給每個(gè)孩子都買一份玩具,各自玩各自的就不會(huì)有問題了。

1.2 深拷貝

如果一個(gè)類中涉及到資源的管理,其拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載以及析構(gòu)函數(shù)必須要顯式給出。一般情況都是按照深拷貝方式提供。

1.3 傳統(tǒng)版寫法的String類

//傳統(tǒng)寫法
string::string(const string& s)
{
  _str = new char[s._capacity + 1];
	//strcpy不能拷貝中間有'\0'的字符串
	//strcpy(_str, s._str);
	memcpy(_str, s._str, s._size + 1);
	_size = s._size;
	_capacity = s._capacity;
}
//傳統(tǒng)寫法
//s1=s3
string& string::operator=(const string& s)
{
	//&s是取地址操作
	//如果不是自己給自己賦值就開空間 
	if (this != &s)
	{
		//開一樣的空間,再賦值
		char* tmp = new char[s._capacity + 1];
		strcpy(tmp, s._str);
		delete[] _str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
	}
	return *this;
}

1.4 現(xiàn)代版寫法的String類

//現(xiàn)代寫法:本質(zhì)效率沒有提升,只是寫法不同
string::string(const string& s)
{
	//this指針沒初始化,可能有風(fēng)險(xiǎn),所以可以在聲明變量時(shí)可以設(shè)置默認(rèn)參數(shù)
	//private:
	//	char* _str=nullptr;
	//	size_t _size=0;
	//	size_t _capacity=0;
	string tmp(s._str);
	swap(tmp);
}
//現(xiàn)代寫法
string& string::operator=(const string& s)
{
	if (this != &s)
	{
		string tmp(s._str);
		swap(tmp);
	}
	return *this;
}
//現(xiàn)代寫法更簡潔版
string& string::operator=(string tmp)
{
	swap(tmp);
	return *this;
}

1.4 寫時(shí)拷貝(了解)

寫時(shí)拷貝就是一種拖延癥,是在淺拷貝的基礎(chǔ)之上增加了引用計(jì)數(shù)的方式來實(shí)現(xiàn)的。

引用計(jì)數(shù):用來記錄資源使用者的個(gè)數(shù)。在構(gòu)造時(shí),將資源的計(jì)數(shù)給成1,每增加一個(gè)對(duì)象使用該資源,就給計(jì)數(shù)增加1,當(dāng)某個(gè)對(duì)象被銷毀時(shí),先給該計(jì)數(shù)減1,然后再檢查是否需要釋放資源,如果計(jì)數(shù)為1,說明該對(duì)象時(shí)資源的最后一個(gè)使用者,將該資源釋放;否則就不能釋放,因?yàn)檫€有其他對(duì)象在使用該資源

1.5 string類的模擬實(shí)現(xiàn)

構(gòu)造函數(shù)和析構(gòu)函數(shù)不能有返回值

string模擬實(shí)現(xiàn)參考

//string.h
#pragma once
#include<iostream>
//strlen需要包含的
#include<string.h>
#include<assert.h>
#include<algorithm>
using namespace std;
//string與庫里有命名沖突
namespace bit
{
	class string
	{
	public:
		//1)[]下標(biāo)訪問
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}
		//2)范圍for底層是迭代器
		typedef char* iterator;
		typedef const char* const_iterator;//內(nèi)容不能修改
		//開始位置的迭代器
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		size_t size() const
		{
			return _size;
		}
		const char* c_str() const
		{
			return _str;
		}
		//常量字符串默認(rèn)結(jié)尾有'\0'
		string(const char* str = "");
		~string();
		string(const string& s);
		string& operator=(const string& s);
		void reserve(size_t n);
		void push_back(char ch);
		void append(const char* str);
		//清除數(shù)據(jù)
		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		void resize(size_t n, char ch = '\0');
		void insert(size_t pos, char ch);
		void insert(size_t pos, const char* str);
		void erase(size_t pos=0, size_t len=npos);
		size_t find(char ch, size_t pos = 0);
		size_t find(const char* str, size_t pos = 0);
		string substr(size_t pos = 0, size_t len = npos);
		void swap(string& s);
		bool operator<(const string& s) const;
		bool operator<= (const string & s) const;
		bool operator>(const string& s) const;
		bool operator>=(const string& s) const;
		bool operator==(const string& s) const;
		bool operator!=(const string& s) const;
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	public:
		//在.cpp中定義,但是const static整型可以這么用,特殊處理
		const static size_t npos=-1;
		//double不支持
		//const static double npos = 1.0;
	};
	std::ostream& operator<<(std::ostream& out, const string& s);
	std::istream& operator>>(std::istream& in, string& s);
	std::istream& getline(std::istream& in, string& str, char delim = '\n');
}
//string.cpp
#include"string.h"
namespace bit
{
	//_str要預(yù)留一個(gè)字節(jié)存'\0'
	//string()
	//	:_str(new char[1] {'\0'} )
	//		, _size(0)
	//		, _capacity(0)
	//{}
	string::string(const char* str)
		:_size(strlen(str))
	{
		//不能用sizeof,只能計(jì)算數(shù)組大小
		_str = new char[_size + 1];
		_capacity = _size;
		strcpy(_str, str);
	}
	//析構(gòu)未完成
	string::~string()
	{
		delete[] _str;
		_str = nullptr;
		_size = 0;
		_capacity = 0;
	}
	void string::reserve(size_t n)
	{
		//永遠(yuǎn)多開一個(gè)空間
		//capacity和size是有效數(shù)字個(gè)數(shù)
		if (n > _capacity)
		{
			//擴(kuò)容
			char* tmp = new char[n + 1];
			//strcpy(tmp, _str);
			memcpy(tmp, _str, _size + 1);
			delete[] _str;
			_str = tmp;
			_capacity = n;
		}
	}
	void string::push_back(char ch)
	{
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		_str[_size] = ch;
		_size++;
		_str[_size] = '\0';
	}
	//添加字符
	void string::append(const char* str)
	{
		size_t len = strlen(str);
		if (_size + len > _capacity)
		{
			reserve(std::max(_size + len, _capacity * 2));
		}
		//strcpy(_str + _size, str);
		memcpy(_str + _size, str, len + 1);
		_size += len;
	}
	void string::insert(size_t pos, char ch)
	{
		//可以在'\0'(下標(biāo)為_size)位置直接插
		assert(pos <= _size);
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		//挪動(dòng)數(shù)據(jù)
		size_t end = _size + 1;
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			--end;
		}
		_str[pos] = ch;
		++_size;
	}
	void string::insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t len = strlen(str);
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
		//挪動(dòng)數(shù)據(jù),第一種方法
		//(int)pos 將 pos 強(qiáng)制轉(zhuǎn)換為 int
		//是為了避免 end(有符號(hào) int)與無符號(hào) pos(通常 size_t)比較時(shí)可能出現(xiàn)的無符號(hào)整數(shù)回繞問題
		//例如當(dāng) pos=0 時(shí),如果 end 是無符號(hào)且遞減到 0,再減 1 會(huì)變成極大值,導(dǎo)致無限循環(huán)
		//這里 end 是 int,pos 轉(zhuǎn)成 int,比較在 int 域中進(jìn)行,安全。
		/*int end = _size;
		while (end > (int)pos)
		{
			_str[end+len] = _str[end];
			--end;
		}
		strncpy(_str + pos, str, len);
		_size += len;*/
		size_t end = _size + len;
		while (end > pos + len - 1)
		{
			_str[end] = _str[end - len];
			--end;
		}
		//strncpy(_str + pos, str, len);為了統(tǒng)一寫成下面這種
		memcpy(_str + pos, str, len);
		_size += len;
	}
	void string::erase(size_t pos, size_t len)
	{
		//刪除有效字符個(gè)數(shù),不是assert(pos <= _size);
		assert(pos < _size);
		//說明刪除后面所有
		//npos是整型的最大值,len==npos就是刪完所有的意思
		if (len == npos || len >= _size - pos)
		{
			//直接覆蓋
			_size = pos;
			_str[_size] = '\0';
		}
		else
		{
			//刪除部分
			//把后面往前覆蓋
			//strcpy(_str + pos , _str + pos + len);
			//需要移動(dòng)的長度[str+pos+len,_size],左閉右閉,左減右+1
			memcpy(_str + pos, _str + pos + len, _size - (pos + len) + 1);
			_size -= len;
		}
	}
	//傳統(tǒng)寫法
	//string::string(const string& s)
	//{
	//	_str = new char[s._capacity + 1];
	//	//strcpy不能拷貝中間有'\0'的字符串
	//	//strcpy(_str, s._str);
	//	memcpy(_str, s._str, s._size + 1);
	//	_size = s._size;
	//	_capacity = s._capacity;
	//}
	//現(xiàn)代寫法:本質(zhì)效率沒有提升,只是寫法不同
	string::string(const string& s)
	{
		//this指針沒初始化,可能有風(fēng)險(xiǎn),所以可以在聲明變量時(shí)可以設(shè)置默認(rèn)參數(shù)
		//private:
		//	char* _str=nullptr;
		//	size_t _size=0;
		//	size_t _capacity=0;
		string tmp(s._str);
		swap(tmp);
	}
	//傳統(tǒng)寫法
	//s1=s3
	//string& string::operator=(const string& s)
	//{
	//	//&s是取地址操作
	//	//如果不是自己給自己賦值就開空間 
	//	if (this != &s)
	//	{
	//		//開一樣的空間,再賦值
	//		char* tmp = new char[s._capacity + 1];
	//		strcpy(tmp, s._str);
	//		delete[] _str;
	//		_str = tmp;
	//		_size = s._size;
	//		_capacity = s._capacity;
	//	}
	//	return *this;
	//}
	//現(xiàn)代寫法
	string& string::operator=(const string& s)
	{
		if (this != &s)
		{
			string tmp(s._str);
			swap(tmp);
		}
		return *this;
	}
	//現(xiàn)代寫法更簡潔版
	//string& string::operator=(string tmp)
	//{
	//	swap(tmp);
	//	return *this;
	//}
	std::ostream& operator<<(std::ostream& out, const string& s)
	{
		for (auto ch : s)
		{
			cout << ch;
		}
		return out;
	}
	//改變?nèi)萜鞯拇笮?,多余空間賦值ch
	void string::resize(size_t n, char ch)
	{
		if (n <= _size)
		{
			//刪除,保留前n個(gè)
			_size = n;
			_str[_size] = '\0';
		}
		else
		{
			reserve(n);
			for (size_t i = _size; i < n; i++)
			{
				_str[i] = ch;
			}
			_size = n;
			_str[_size] = '\0';
		}
	}
	size_t string::find(char ch, size_t pos)
	{
		assert(pos < _size);
		for (size_t i = pos; i < _size; i++)\
		{
			if (_str[i] == ch)
				return i;
		}
		return npos;
	}
	size_t string::find(const char* str, size_t pos)
	{
		//找到對(duì)應(yīng)指針,否則返回空
		const char* ptr = strstr(_str + pos, str);
		//如果找到讓它返回下標(biāo)
		if (ptr)
			return ptr - str;
		else
			return npos;
	}
	//從字符串pos位置提取n個(gè)字符拷貝
	string string::substr(size_t pos, size_t len)
	{
		assert(pos < _size);
		if (len == npos || len >= _size - pos)
		{
			len = _size - pos;
		}
		string sub;
		reserve(len);
		for (size_t i = 0; i < len; i++)
		{
			sub += _str[pos + i];
		}
		return sub;
	}
	std::istream& operator>>(std::istream& in, string& s)
	{
		s.clear();
		char buff[256];
		int i = 0;
		char ch;
		//這樣寫讀取不到' '
		//in >> ch;
		ch = in.get();
		while (ch != '\n' && ch != ' ')
		{
			buff[i++] = ch;
			//長的字符串
			if (i == 255)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get(); 
		}
		//短的字符串
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
	bool string::operator<(const string& s) const
	{
		return strcmp(_str, s._str) < 0;
	}
	bool string::operator<= (const string & s) const
	{
		return *this < s || *this == s;
	}
	bool string::operator>(const string& s) const
	{
		return !(*this <= s);
	}
	bool string::operator>=(const string& s) const
	{
		return!(*this < s);
	}
	bool string::operator==(const string& s) const
	{
		return strcmp(_str, s._str) == 0;
	}
	bool string::operator!=(const string& s) const
	{
		return !(*this == s);
	}
	std::istream& getline(std::istream& in, string& s, char delim)
	{
		s.clear();
		char buff[256];
		int i = 0;
		char ch;
		//這樣寫讀取不到' '
		//in >> ch;
		ch = in.get();
		while (ch != delim )
		{
			buff[i++] = ch;
			//長的字符串
			if (i == 255)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		//短的字符串
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
	//庫里的swap函數(shù),會(huì)拷貝三次,代價(jià)太大,下面的更高效
	void string::swap(string& s)
	{
		std::swap(_str, s._str);
		std::swap(_size, s._size);
		std::swap(_capacity, s._capacity);
	}
}
//test.cpp
#include"string.h"
namespace bit
{	
	void test_string1()
	{
		string s1;
		cout << s1.c_str() << endl;
		string s2("hello world");
		cout << s2.c_str() << endl;
		s2[0] = 'x';
		cout << s2.c_str() << endl;
		for (size_t i = 0; i < s2.size(); i++)
		{
			s2[i]++;
		}
		cout << s2.c_str() << endl;
		const string s3 = "hello world";//隱式類型轉(zhuǎn)換,構(gòu)造+拷貝構(gòu)造->優(yōu)化為構(gòu)造
		for (size_t i = 0; i < s3.size(); i++)
		{
			cout << s3[i] << '-';
		}
		cout << endl;
		for (auto ch : s3)
		{
			cout << ch << " ";
		}
		cout << endl;
		string s4 = "hello world";
		string::iterator it4 = s4.begin();
		while (it4 != s4.end())
		{
			*it4 += 1;
			//類似指針
			cout << *it4 << "  ";
			++it4;
		}
		string::const_iterator it3 = s3.begin();
		while (it3 != s3.end())
		{
			//類似指針
			cout << *it3 << "  ";
			++it3;
		}
	}
	void test_string2()
	{
		bit::string s1;
		cout << s1.c_str() << endl;
		string s2("hello world");
		cout << s2.c_str() << endl;
		s2.push_back('x');
		s2.push_back('y');
		s2.push_back('z');
		cout << s2.c_str() << endl;
		string s3("hello");
		s3.append("xxxxxxxxxxxxxxxxxx");
		cout << s3.c_str() << endl;
		string s4("world");
		s4.append("xx");
		cout << s4.c_str() << endl;
		s4+= '*';
		s4 += "hello bit";
		cout << s4.c_str() << endl;
	}
	void test_string3()
	{
		string s1("hello world");
		cout << s1.c_str() << endl;
		s1.insert(5, 'x');
		cout << s1.c_str() << endl;
		string s2("hello world");
		cout << s2.c_str() << endl;
		s2.insert(5, "yyy");
		cout << s2.c_str() << endl;
	}
	void test_string4()
	{
		string s1("hello world");
		cout << s1.c_str() << endl;
		s1.erase(5, 2);
		cout << s1.c_str() << endl;
		string s2("hello world");
		cout << s2.c_str() << endl;
		s2.erase(5);
		cout << s2.c_str() << endl;
		string s3("hello world");
		cout << s3.c_str() << endl;
		s3.erase(5,100);
		cout << s3.c_str() << endl;
	}
	void test_string5()
	{
		//默認(rèn)生成的構(gòu)造是淺拷貝,會(huì)導(dǎo)致s1和s2指向同一空間,析構(gòu)兩次
		string s1("hello world");
		string s2(s1);
		s1[0] = 'x';
		cout << s1.c_str() << endl;
		cout << s2.c_str() << endl;
		//賦值重載
		string s3("hello worldxxxxxx");
		s1 = s3;
		cout << s1.c_str() << endl;
		cout << s3.c_str() << endl;
	}
	void test_string6()
	{
		//字符串中間可以有'\0'這個(gè)有效字符
		string s1("hello world");
		s1 += 'x';
		s1 += '\0';
		s1 += "yyy";
		cout << s1 << endl;
		cout << s1.c_str() << endl;
		//對(duì)中間有'\0'的字符拷貝
		string s2(s1);
		cout << s1 << endl;
		cout << s2 << endl;
	}
	void test_string7()
	{
		string s1;
		s1.resize(100, '*');
		cout << s1 << endl;
		s1.resize(10);
		cout << s1 << endl;
		s1.resize(20, '#');
		cout << s1 << endl;
	}
	void test_string8()
	{
		string ur1 = "https://cplusplus.com/reference/string/string/rfind/";
		//分離網(wǎng)絡(luò)協(xié)議
		size_t i1 = ur1.find(':');
		if (i1 != string::npos)
		{
			//protocol協(xié)議
			string protocol = ur1.substr(0, i1);
			cout << protocol << endl;
			//分離域名
			size_t i2 = ur1.find('/', i1 + 3);
			if (i2 != string::npos)
			{
				string domain = ur1.substr(i1 + 3, i2 - (i1 + 3));
				cout << domain << endl;
				//分離最后
				string uri = ur1.substr(i2 + 1);
				cout << uri << endl;
			}
		}
	}
	void test_string9()
	{
		string s1,s2("xxxxx");
		cin >> s1>>s2;
		cout << s1 << endl;
		cout << s2 << endl;
		getline(cin,s1);
		cout << s1 << endl;
	}
	void test_string10()
	{
		string s1("hello world"), s2("xxxxx");
		s1.swap(s2);
		cout << s1 << endl;
		cout << s2 << endl;
	}
}
int main()
{
	//bit::test_string1();
	//bit::test_string2();
	//bit::test_string3();
	//bit::test_string4();
	//bit::test_string5();
	//bit::test_string6();
	//bit::test_string7();
	//bit::test_string8();
	//bit::test_string9();
	bit::test_string10();
	return 0;
}

1.6 vs和g++下string結(jié)構(gòu)的說明

注意:下述結(jié)構(gòu)是在32位平臺(tái)下進(jìn)行驗(yàn)證,32位平臺(tái)下指針占4個(gè)字節(jié)。

  • vs下string的結(jié)構(gòu)

string總共占28個(gè)字節(jié),內(nèi)部結(jié)構(gòu)稍微復(fù)雜一點(diǎn),先是有一個(gè)聯(lián)合體,聯(lián)合體用來定義string中字符串的存儲(chǔ)空間:

  1. 當(dāng)字符串長度小于16時(shí),使用內(nèi)部固定的字符數(shù)組來存放
  2. 當(dāng)字符串長度大于等于16時(shí),從堆上開辟空間
union _Bxty
{ 
	// storage for small buffer or pointer to larger one
	 value_type _Buf[_BUF_SIZE];
	 pointer _Ptr;
	 char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

這種設(shè)計(jì)也是有一定道理的,大多數(shù)情況下字符串的長度都小于16,那string對(duì)象創(chuàng)建好之后,內(nèi)部已經(jīng)有了16個(gè)字符數(shù)組的固定空間,不需要通過堆創(chuàng)建,效率高。
其次:還有一個(gè)size_t字段保存字符串長度,一個(gè)size_t字段保存從堆上開辟空間總的容量
最后:還有一個(gè)指針做一些其他事情。
故總共占16+4+4+4=28個(gè)字節(jié)。

  • g++下string的結(jié)構(gòu)

G++下,string是通過寫時(shí)拷貝實(shí)現(xiàn)的,string對(duì)象總共占4個(gè)字節(jié),內(nèi)部只包含了一個(gè)指針,該指針將來指向一塊堆空間,內(nèi)部包含了如下字段:

  • 空間總大小
  • 字符串有效長度
  • 引用計(jì)數(shù)
struct _Rep_base
{
 size_type               _M_length;
 size_type               _M_capacity;
 _Atomic_word            _M_refcount;
};
  • 指向堆空間的指針,用來存儲(chǔ)字符串。

1.7 補(bǔ)充的接口

2.擴(kuò)展閱讀

面試中string的一種正確寫法
STL中的string類怎么了?

到此這篇關(guān)于C++ string類擴(kuò)展知識(shí)全解析的文章就介紹到這了,更多相關(guān)C++ string類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)簡單通訊錄

    C++實(shí)現(xiàn)簡單通訊錄

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡單通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 淺析C++中cout的運(yùn)行機(jī)制

    淺析C++中cout的運(yùn)行機(jī)制

    關(guān)于C++中cout的使用,相信大家再熟悉不過了,然而對(duì)于cout是如何輸出的?輸出的機(jī)制是啥,需要進(jìn)一步的了解。本章娓娓道來。前幾天在網(wǎng)上看到這么一個(gè)題目
    2013-10-10
  • Qt中多線程QThread、QThreadPool、QConCurrent三種方式對(duì)比分析

    Qt中多線程QThread、QThreadPool、QConCurrent三種方式對(duì)比分析

    QThread是Qt多線程的基石,本質(zhì)上是對(duì)操作系統(tǒng)原生線程的面向?qū)ο蠓庋b,本文介紹Qt中多線程QThread、QThreadPool、QConCurrent三種方式對(duì)比分析,感興趣的朋友一起看看吧
    2026-05-05
  • C語言時(shí)間函數(shù)之mktime和difftime詳解

    C語言時(shí)間函數(shù)之mktime和difftime詳解

    這篇文章主要為大家詳細(xì)介紹了C語言時(shí)間函數(shù)之mktime和difftime,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一,希望能夠給你帶來幫助
    2022-02-02
  • C語言數(shù)組越界引發(fā)的死循環(huán)問題解決

    C語言數(shù)組越界引發(fā)的死循環(huán)問題解決

    本文主要介紹了C語言數(shù)組越界引發(fā)的死循環(huán)問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的詳細(xì)流程

    win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的詳細(xì)流程

    這篇文章主要介紹了win10系統(tǒng)VS2019配置點(diǎn)云庫PCL1.12.1的教程與經(jīng)驗(yàn)總結(jié),本文記錄小白在配置過程中踩過的一些小坑,需要的朋友可以參考下
    2022-07-07
  • C語言中“不受限制”的字符串函數(shù)總結(jié)

    C語言中“不受限制”的字符串函數(shù)總結(jié)

    這篇文章主要給大家總結(jié)介紹了C語言中一些“不受限制”的字符串函數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++ 實(shí)戰(zhàn)開發(fā)一個(gè)猜單詞的小游戲

    C++ 實(shí)戰(zhàn)開發(fā)一個(gè)猜單詞的小游戲

    眾所周知紙上得來終覺淺,我們要在實(shí)戰(zhàn)中才能真正的掌握技術(shù),小編為大家?guī)硪环萦肅++編寫的猜單詞小游戲,給大家練練手,快來看看吧
    2021-11-11
  • Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題

    Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題

    這篇文章主要介紹了Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • c++虛函數(shù)與虛函數(shù)表原理

    c++虛函數(shù)與虛函數(shù)表原理

    這篇文章主要介紹了c++虛函數(shù)與虛函數(shù)表原理,用virtual?修飾的成員函數(shù)叫虛函數(shù),下面圍繞c++虛函數(shù)與虛函數(shù)得相關(guān)資料展開內(nèi)容,需要的朋友可以參考一下
    2021-12-12

最新評(píng)論

尉犁县| 尉犁县| 客服| 偃师市| 敖汉旗| 永兴县| 金乡县| 潍坊市| 武冈市| 喜德县| 昌吉市| 长春市| 大城县| 兴和县| 怀仁县| 乌海市| 方山县| 西盟| 连南| 宜良县| 武宣县| 永福县| 沅江市| 罗源县| 长丰县| 赤城县| 瓮安县| 秭归县| 黑河市| 洛南县| 濉溪县| 深水埗区| 买车| 赤壁市| 山西省| 兴安县| 泽库县| 宁海县| 织金县| 崇文区| 开化县|