主頁 > 後端開發 > 01章-模板--C++提高編程知識學習筆記

01章-模板--C++提高編程知識學習筆記

2022-09-14 06:11:27 後端開發

1 模板

1.1 模板的概念

模板就是建立通用的模具,大大提高復用性

1.2 函式模板

  • C++另一種編程思想稱為泛型函式,主要利用的技術就是模板
  • C++提供兩種模板機制:函式模板和類模板

1.2.1 函式模板語法

模板函式作用:

建立一個通用函式,其函式回傳值型別和形參型別可以不具體指定,用一個虛擬的型別來代表

語法

template<typename T>
函式宣告或定義

解釋

template --- 宣告創建模板

typename --- 表面其后面的符號是一種資料型別,可以用class代替

T --- 通用的資料型別,名稱可以替換,通常為大寫字母

示例

#include<iostream>
using namespace std;

//函式模板

//兩個整數交換函式
void swapInt(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

//交換兩個浮點型的函式
void swapDouble(double& a, double& b)
{
	double temp = a;
	a = b;
	b = temp;
}

void test01()
{
	int a = 10;
	int b = 20;
	swapInt(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	double c = 1.1;
	double d = 2.2;
	swapDouble(c, d);
	cout << "c = " << c << endl;
	cout << "d = " << d << endl;
}

//函式模板
template <typename T>//宣告一個模板告訴編譯器后面代碼中緊跟著的T不要報錯,T是一個通用的資料型別
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

void test02()
{
	int a = 10;
	int b = 20;

	//1、自動型別推導
	mySwap(a, b);

	//2、顯示指定型別
	mySwap<int>(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
}

int main()
{
	test01();

	test02();

	system("pause");
	return 0;
}

1.2.2 函式模板注意事項

注意事項:

  • 自動型別推導,必須推匯出一致的函式型別T,才可以使用
  • 模板必須要確定出T的資料型別,才可以使用

示例:

#include<iostream>
using namespace std;

//函式模板注意事項

//template<typename T> // typename可以替換成calss

template<class T>
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

//1、自動型別推導,必須推匯出一致的資料型別T才可以使用
void test01()
{
	int a = 10;
	int b = 20;

	char c = 'c';

	mySwap(a, b);//正確
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	//mySwap(a, c);//報錯,無法推匯出一致的資料型別

}

//2、模板必須要確定出T的資料型別,才可以使用
template<class T>
void func()
{
	cout << "func 呼叫" << endl;
}

void test02()
{
	func<int>();//隨便給一個資料型別就能呼叫func模板函式了
}

int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

1.2.3 函式模板案例

案例描述:

  • 利用函式模板封裝成一個排序的函式,可以對不同資料型別陣列進行排序
  • 排序規則從大到小,排序演算法為選擇排序
  • 分別利用char陣列和int陣列進行測驗

示例:

#include <iostream>
using namespace std;

//實作通用 對陣列進行排序的函式
//規則 從大到小
//演算法 選擇
//測驗 char 陣列,int 陣列

//交換函式模板
template<class T>
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

//排序演算法
template<class T>
void mySort(T arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		int max = i;//認定最大值下標
		for (int j = i + 1; j < len; j++)
		{
			//認定的最大值比遍歷出的數值要小,說明j下標的元素才是真正的最大值
			if (arr[max] < arr[j])
			{
				max = j;//更新最大值下標
			}
		}
		if (max != i)
		{
			//交換max和i元素
			mySwap(arr[max], arr[i]);
		}
	}
}

//列印陣列的模板
template<class T>
void printArray(T arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "arr中的第" << i << "元素 = " << arr[i] << endl;
	}
}
void test01()
{
	//測驗char陣列
	char charArr[] = "badcfe";
	
	int num = sizeof(charArr) / sizeof(char);
	mySort(charArr, num);
	printArray(charArr, num);

}

void test02()
{
	//測驗int陣列
	int intArr[] = { 7,5,1,3,10,2,4,7,9 };

	int num = sizeof(intArr) / sizeof(int);

	mySort(intArr, num);
	printArray(intArr, num);
}

int main()
{
	test01();

	test02();

	system("pause");
	return 0;
}

1.2.4 普通函式與函式模板的區別

普通函式與函式模板區別:

  • 普通函式呼叫時可以發生自動型別轉換(隱式型別轉換)
  • 函式模板呼叫時,如果利用自動型別推導,不會發生隱式型別轉換
  • 如果利用顯示指定型別的方式,可以發生隱式型別轉換

示例:

#include <iostream>
using namespace std;

//普通函式與函式模板的區別

//1、普通函式呼叫可以發生隱式型別轉換
//2、函式模板 用自動型別推導,不可以發生隱式型別轉換
//3、函式模板 用顯示指定型別,可以發生隱式型別轉換

//普通函式
int myAdd01(int a, int b)
{
	return a + b;
}

//函式模板
template<class T>
T myAdd02(T a, T b)
{
	return a + b;
}

void test01()
{
	int a = 10;
	int b = 20;

	char  c = 'c'; //c - 99

	cout << myAdd01(a, c) << endl;

	//自動型別推導
	//cout << myAdd02(a, c) << endl;//報錯,函式模板不可以發生隱式型別轉換

	//顯示指定型別
	cout << myAdd02<int>(a, c) << endl;//明確型別,正確
}

int main()
{
	test01();

	system("pause");
	return 0;
}

1.2.5 普通函式與函式模板的呼叫規則

呼叫規則如下:

  • 如果函式模板和普通函式可以實作,優先呼叫普通函式
  • 可以通過空模板引數串列來強調函式模板
  • 函式模板也可以發生多載
  • 如果函式模板可以產生更好的匹配優先呼叫函式模板

示例:

#include<iostream>
using namespace std;

//普通函式與函式模板呼叫規則
//1、如果函式模板和普通函式都可以呼叫,優先呼叫普通函式
//2、可以通過空模板引數串列 強制呼叫 函式模板
//3、函式模板可以發生函式多載
//4、如果函式模板可以產生更好的匹配,優先呼叫函式模板

void myPrint(int a, int b)//如果只有宣告,沒有函式實作,就會報錯,還是優先呼叫普通函式
{
	cout << "呼叫普通函式" << endl;
}

template<class T>
void myPrint(T a, T b)
{
	cout << "呼叫模板" << endl;
}

template<class T>
void myPrint(T a, T b,T c)
{
	cout << "呼叫多載的模板" << endl;
}

void test01()//優先呼叫普通函式
{
	int a = 10;
	int b = 10;
	myPrint(a, b);//呼叫普通函式

	//通過空模板的引數串列,強制呼叫函式模板
	myPrint<>(a, b);//呼叫函式模板

	myPrint(a, b, 100);//呼叫多載函式模板

	//如果函式模板產生更好的匹配,優先呼叫函式模板
	char c1 = 'a';
	char c2 = 'b';
	myPrint(c1, c2);//呼叫函式模板

}

int main()
{
	test01();

	system("pause");
	return 0;
}

總結:既然提供了函式模板,最好就不要提供普通函式了,容易產生二義性,實際開發中這樣子意義不大,

1.2.6 模板的局限性

局限性:

  • 模板的通用性并不是萬能的

例如

template<class T>
void f(T a, T b)
{
    a = b;
}

在上述代碼中提供了賦值操作,如果傳入a和b是一個陣列,就無法實作了,

再例如

template<class T>
void f(T a, T b)
{
    if(a > b){...}
}

在上述代碼中,如果T的資料型別傳入的是像Person的自定義資料型別,也是無法正常運行的,

因此為了解決這類問題,提供模板的多載,可以為這些特定的型別提供具體化的模板

示例:

#include<iostream>
#include<string>
using namespace std;

//模板的局限性
//模板并不是萬能的,有些特定的資料型別,需要用具體化的方式做實作

//對比兩個資料型別是否相等函式

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Age = age;
		this->m_Name = name;
	}
	string m_Name;
	int m_Age;
};

template<class T>
bool myCompare(T& a, T& b)
{
	if (a == b)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//利用具體化的Person的版本實作代碼,具體化優先呼叫
template<> bool myCompare(Person& p1, Person& p2)
{
	if (p1.m_Age == p2.m_Age && p1.m_Name == p2.m_Name)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void test01()
{
	int a = 10;
	int b = 20;

	bool ret = myCompare(a, b);

	if (ret)
	{
		cout << "a == b" << endl;
	}
	else
	{
		cout << "a != b" << endl;	
	}
}

void test02()
{
	Person p1("Tom", 10);
	Person p2("Tom", 10);

	bool ret = myCompare(p1, p2);

	if (ret)
	{
		cout << "p1 == p2" << endl;
	}
	else
	{
		cout << "p1 != p2" << endl;
	}

}

int main()
{
	test01();
	
	test02();

	system("pause");
	return 0;
}

總結:

  • 利用具體化的模板,可以解決自定義型別的通用化
  • 學習模板并不是為了寫模板,而是在STL能夠運用系統提供的模板

1.3 類模板

1.3.1 類模板語法

類模板作用:

  • 建立一個通用類,類中成員資料型別可以不具體指定,用一個虛擬的型別來代表

語法:

template<typname T>
類

解釋:

template --- 宣告創建模板

typename --- 表明其后面的符號是一種資料型別,可以用class代替

T --- 通用的資料型別,名稱可以替換,通常為大寫字母

示例:

#include<iostream>
#include<string>
using namespace std;
//類模板
template<class NameType, class AgeType>

class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeType m_Age;
	void showPerson()
	{
		cout << "name: " << this->m_Name << " age: " << this->m_Age << endl;
	}
};

void test01()
{
	Person<string, int>p1("孫悟空", 999);
	p1.showPerson();
}

int main()
{
	test01();
	system("pause");
	return 0;
}

1.3.2 類模板與函式模板區別

類模板與函式模板區別主要有兩點:

  1. 類模板沒有自動型別推導的使用方式
  2. 類模板在模板引數串列中可以有模板引數

示例

#include<iostream>
#include<string>
using namespace std;

//類模板與函式模板區別
template<class NameType, class AgeType = int>
class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeType m_Age;
	void showPerson()
	{
		cout << "name: " << this->m_Name << " age: " << this->m_Age << endl;
	}
};

//1、類模板沒有自動型別推導使用方式
void test01()
{
	//Person p("孫悟空",999)//錯誤,無法用自動型別推導
	Person<string, int>p("孫悟空", 999);
	p.showPerson();
}
//2、類模板在模板引數串列中可以有默認引數
void test02()
{
	Person<string>p("豬八戒", 1000);
	p.showPerson();
}

int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

1.3.3 類模板中成員函式創建時機

類模板中成員函式和普通類中成員函式創建時機是有去別的:

  • 普通類中的成員函式一開始就可以創建
  • 類模板中的成員函式在呼叫時才創建

示例

#include<iostream>
using namespace std;

//類模板中成員函式創建時機
//類模板中成員函式在呼叫時才去創建

class Pesrson1
{
public:
	void showPerson1()
	{
		cout << "Person1 show!" << endl;
	}
};

class Pesrson2
{
public:
	void showPerson2()
	{
		cout << "Person2 show!" << endl;
	}
};

template<class T>
class MyClass
{
public:
	T obj;

	//類模板中的成員函式//是在 被呼叫時候才會創建的,需要確認是什么成員函式型別之后才能被呼叫,不然呼叫不出來,
	void func1()
	{
		obj.showPerson1();
	}
	void func2()
	{
		obj.showPerson2();
	}
};

void test01()
{
	MyClass<Pesrson1> m;
	m.func1();
	//m.func2();
}

int main()
{
	test01();
	system("pause");
	return 0;
}

總結:類模板中的成員函式不是一開始就創建的,在呼叫時才去創建的,

1.3.4 類模板物件做函式引數

學習目標:

  • 類模板實體化出的物件,向函式傳參的方式

一共有三種傳入方式:

  1. 指定傳入的型別 --- 直接顯示物件的資料型別
  2. 引數模板化 --- 將物件中的引數變為模板進行傳遞
  3. 整個類模板化 --- 將整個物件型別 模板化進行傳遞

示例:

#include<iostream>
#include<string>
using namespace std;

//類模板物件做函式引數

template<class T1, class T2>
class Person
{
public:
	Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;

	}
	void showPerson()
	{
		cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
	}
	T1 m_Name;
	T2 m_Age;
};

//1、指定傳入型別 //最常用
void printPerson1(Person<string,int>&p)
{
	p.showPerson();
}

void test01()
{
	Person<string, int>p("孫悟空", 100);
	printPerson1(p);
}

//2、將引數模板化
template<class T1, class T2>
void printPerson2(Person<T1, T2>& p)
{
	p.showPerson();
	cout << "T1 的型別為:" << typeid(T1).name() << endl;
	cout << "T2 的型別為:" << typeid(T2).name() << endl;
}
void test02()
{
	Person<string, int>p("豬八戒", 1000);
	printPerson2(p);
}
//3、整個類模板化
template<class T>
void printPerson3(T& p)
{
	p.showPerson();
}

void test03()
{
	Person<string, int>p("唐僧", 30);
	printPerson3(p);
}

int main()
{
	test01();
	test02();
	test03();
	system("pause");
	return 0;
}

總結:

  • 通過類模板創建的物件,可以有三種方式向函式中進行傳參
  • 比較廣泛使用的方式是指定傳入型別

1.3.5 類模板與繼承

當類模板碰到繼承時,需要注意以下幾點:

  • 當子類繼承的父類是一個類模板時,子類在宣告的時候,要指定出父類中T的型別
  • 如果不指定,編譯器無法給子類分配記憶體
  • 如果想靈活指定出父類中T的型別,子類也需變為類模板

示例:

#include<iostream>
using namespace std;

//類模板與繼承
template<class T>
class Base
{
	T m;
};

//class Son :public Base//錯誤,必須知道父類中的T型別,才能繼承子類
class Son:public Base<int>
{

};

void test01()
{
	Son s1;
}

//如果想要靈活的指定父類中T的型別,子類也需要邊類模板
template<class T1, class T2>
class Son2 :public Base<T2>
{
	T1 obj;
};

void test02()
{
	Son2<int, char>S2;

}

int main()
{
	test01();

	test02();
	system("pause");
	return 0;
}

1.3.6 類模板成員函式類外實作

學習目標:能夠掌握類模板中的成員函式類外實作

示例:

#include<iostream>
#include<string>
using namespace std;
//類模板成員函式類外實作
template<class T1, class T2>
class Person
{
public:
	Person(T1 name, T2 age);
//	Person(T1 name, T2 age)
//	{
//		this->m_Name = name;
//		this->m_Age = age;
//	}
	
	void showPerson();
	//{
	//	cout << "姓名: " << m_Name << " 年齡:" << m_Age << endl;
	//}

	T1 m_Name;
	T2 m_Age;
};


//建構式的類外實作
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
	this->m_Name = name;
	this->m_Age = age;
}

//成員函式類外實作
template<class T1 ,class T2>
void Person<T1, T2>::showPerson()
{
	cout << "姓名: " << m_Name << " 年齡:" << m_Age << endl;
}

void test01()
{
	Person<string, int>p("Tom", 20);
	p.showPerson();
}

int main()
{
	test01();
	system("pause");
	return 0;
}

總結:類模板中成員函式類外實作時,需要加上模板引數串列

1.3.7 類模板分檔案撰寫

學習目標:

  • 掌握類模板成員函式分檔案撰寫產生的問題以及解決方式

問題:

  • 類模板中成員函式創建時機是在呼叫階段,導致份檔案撰寫時鏈接不到

解決:

  • 解決方式1:直接包含.cpp源檔案
  • 解決方式2:將宣告和實作卸載同一個檔案中,并更改后綴為.hpp,hpp是約定的名稱,并不是強制

創建.hpp

示例:

#pragma once
#include<iostream>
#include<string>
using namespace std;
template<class T1, class T2>
class Person
{
public:
	Person(T1 name, T2 age);
	void showPerson();
	T1 m_Name;
	T2 m_Age;
};


template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
	this->m_Age = age;
	this->m_Name = name;
}

template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
	cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
}

cpp

#include<iostream>
#include<string >
using namespace std;
#include"person.hpp"

//template<class T1, class T2>
//class Person
//{
//public:
//	Person(T1 name, T2 age);
//	void showPerson();
//	T1 m_Name;
//	T2 m_Age;
//};

//template<class T1, class T2>
//Person<T1, T2>::Person(T1 name, T2 age)
//{
//	this->m_Age = age;
//	this->m_Name = name;
//}
//
//template<class T1, class T2>
//void Person<T1, T2>::showPerson()
//{
//	cout << "姓名:" << this->m_Name << " 年齡:" << this->m_Age << endl;
//}
// 

//2、解決方法 將.h和.cpp內容寫在一起,將后綴名改為.hpp檔案


void test01()
{
	Person<string, int>p("Jerry", 18);
	p.showPerson();
}
int main()
{
	test01();
	system("pause");
	return 0;
}

1.3.8 類模板與友元

學習目標:

  • 掌握類模板配合友元函式的類內和類外實作

全域函式類內實作-直接在類內宣告友元即可

全域函式類外實作-需要提前讓編譯器知道全域函式的存在

示例:

#include<iostream>
#include<string>
using namespace std;

//提前讓編譯器知道類模板
template<class T1, class T2>
class Person;
//類外實作
template<class T1, class T2>
void printPerson2(Person<T1, T2>p)
{
	cout << "類外實作:" << "姓名:" << p.m_Name << " 年齡:" << p.m_Age << endl;
}

//通過全域函式 列印Person資訊

template<class T1, class T2>
class Person
{
	// 全域函式 類內實作
	friend void printPerson(Person<T1, T2>p)
	{
		cout << "姓名:" << p.m_Name << " 年齡:" << p.m_Age << endl;
	}

	//全域函式 類外實作
	//加空引數串列
	//如果全域函式是類外實作需要讓編譯器提前知道這個類模板的存在
	friend void printPerson2<>(Person<T1, T2>p);

public:
	Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

private:
	T1 m_Name;
	T2 m_Age;
};



void test01()
{
	Person<string, int>p("Tom", 20);
	printPerson(p);
}


void test02()
{
	Person<string, int>p ("Jerry", 20);
	printPerson2(p);
}

int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

總結:建議全域函式做類內實作,用法簡單,而且編譯器可以直接識別

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/507110.html

標籤:C++

上一篇:C++ 指標與二維陣列名

下一篇:C++ 一級指標與 const 關鍵字

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more