c++学习笔记(5)

151、模板类的示例-栈
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// typedef string DataType; // 定义栈元素的数据类型。
template <class DataType>
class Stack // 栈类
{
private:
DataType* items; // 栈数组。
int stacksize; // 栈实际的大小。
int top; // 栈顶指针。
public:
// 构造函数:1)分配栈数组内存;2)把栈顶指针初始化为 0。
Stack(int size) :stacksize(size), top(0) {
items = new DataType[stacksize];
}~Stack() {
delete [] items; items = nullptr;
}
bool isempty() const { // 判断栈是否为空。
return top == 0;
}
bool isfull() const { // 判断栈是否已满。
return top == stacksize;
}
bool push(const DataType& item) { // 元素入栈。
if (top < stacksize) { items[top++] = item; return true; }
return false;
}
bool pop(DataType& item) { // 元素出栈。
if (top > 0) { item = items[--top]; return true; }
return false;
}
};
int main()
{
Stack<string> ss(5); // 创建栈对象,大小是 5。
// 元素入栈。
// ss.push(1); ss.push(2); ss.push(3); ss.push(4); ss.push(5);
ss.push("西施"); ss.push("冰冰"); ss.push("幂幂"); ss.push("金莲");
// 元素出栈。
string item;
while (ss.isempty() == false)
{
ss.pop(item); cout << "item = " << item << endl;
}
}
152、模板类的示例-数组
类模板可以有非通用类型参数:1)通常是整型(C++20 标准可以用其它的类型);2)实例化模板
时必须用常量表达式;3)模板中不能修改参数的值;4)可以为非通用类型参数提供默认值。
优点:在栈上分配内存,易维护,执行速度快,合适小型数组。
缺点:在程序中,不同的非通用类型参数将导致编译器生成不同的类。
构造函数的方法更通用,因为数据的大小是类的成员(而不是硬编码),可以创建数组大小可变的类。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template <class T,int len=10>
class Array
{
private:
T items[len]; // 数组元素。
public:
Array() {} // 默认构造函数。
~Array() {} // 析构函数
T& operator[](int ii) { return items[ii]; } // 重载操作符[],可以修改数组中的元素。
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
template <class T>
class Vector
{
private:
int len; // 数组元素的个数。
T* items; // 数组元素。
public:
// 默认构造函数,分配内存。
Vector(int size=10):len(size) {
items = new T[len];
}~Vector() { // 析构函数
delete[] items; items = nullptr;
}
void resize(int size) { // 护展数组的内存空间。
if (size <= len) return; // 只能往更大扩展。
T* tmp = new T[size]; // 分配更大的内存空间。
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii]; // 把原来数组中的元素复制到新数组。
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
int size() const { return len; } // 获取数组长度。
T& operator[](int ii) { // 重载操作符[],可以修改数组中的元素。
if (ii >= len) resize(ii + 1); // 扩展数组。
return items[ii];
}
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
int main()
{
// Array<string,10> aa; // 创建模板类 Array 的对象。
Vector<int> aa(1); // 创建模板类 Vector 的对象。
aa[0] = 5; aa[1] = 8; aa[2] = 3; aa[3] = 2; aa[4] = 7;
// aa[0] = "西施"; aa[1] = "冰冰"; aa[2] = "幂幂"; aa[3] = "金莲"; aa[4] = "小乔";
for (int ii=0; ii<5;ii++) cout << "aa[" << ii << "]=" << aa[ii] << endl;
}
153、嵌套和递归使用模板类
在 C++11 之前,嵌套使用模板类的时候,> >之间要加空格。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template <class DataType>
class Stack // 栈类
{
private:
DataType* items; // 栈数组。
int stacksize; // 栈实际的大小。
int top; // 栈顶指针。
public:
// 构造函数:1)分配栈数组内存;2)把栈顶指针初始化为 0。
Stack(int size = 3) :stacksize(size), top(0) {
items = new DataType[stacksize];
}~Stack() {
delete[] items; items = nullptr;
}
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
delete[] items; // 释放原内存。
stacksize = v.stacksize; // 栈实际的大小。
items = new DataType[stacksize]; // 重新分配数组。
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
top = v.top; // 栈顶指针。
return *this;
}
bool isempty() const { // 判断栈是否为空。
return top == 0;
}
bool isfull() const { // 判断栈是否已满。
return top == stacksize;
}
bool push(const DataType& item) { // 元素入栈。
if (top < stacksize) { items[top++] = item; return true; }
return false;
}
bool pop(DataType& item) { // 元素出栈。
if (top > 0) { item = items[--top]; return true; }
return false;
}
};
template <class T>
class Vector // 动态数组。
{
private:
int len; // 数组元素的个数。
T* items; // 数组元素。
public:
// 默认构造函数,分配内存。
Vector(int size = 2) :len(size) {
items = new T[len];
}~Vector() { // 析构函数
delete[] items; items = nullptr;
}
Vector& operator=(const Vector& v) // 重载赋值运算符函数,实现深拷贝。
{
delete[] items; // 释放原内存。
len = v.len; // 数组实际的大小。
items = new T[len]; // 重新分配数组。
for (int ii = 0; ii < len; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
return *this;
}
void resize(int size) { // 护展数组的内存空间。
if (size <= len) return; // 只能往更大扩展。
T* tmp = new T[size]; // 分配更大的内存空间。
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii]; // 把原来数组中的元素复制到新数组。
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
int size() const { return len; } // 获取数组长度。
T& operator[](int ii) { // 重载操作符[],可以修改数组中的元素。
if (ii >= len) resize(ii + 1); // 扩展数组。
return items[ii];
}
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
int main()
{
// Vector 容器的大小缺省值是 2,Stack 容器的大小缺省值是 3。
// 创建 Vector 容器,容器中的元素用 Stack<string>。
Vector<Stack<string>> vs; // C++11 之前,>>之间要加空格。
// 手工的往容器中插入数据。
vs[0].push("西施 1"); vs[0].push("西施 2"); vs[0].push("西施 3"); // vs 容器中的第 0
个栈。
vs[1].push("西瓜 1"); vs[1].push("西瓜 2"); vs[1].push("西瓜 3"); // vs 容器中的第 1
个栈。
vs[2].push("冰冰"); vs[2].push("幂幂"); //
vs 容器中的第 2 个栈。
// 用嵌套的循环,把 vs 容器中的数据显示出来。
for (int ii = 0; ii < vs.size(); ii++) // 遍历 Vector 容器。
{
while (vs[ii].isempty() == false) // 遍历 Stack 容器。
{
string item; vs[ii].pop(item); cout << "item = " << item << endl;
}
}
// 创建 Stack 容器,容器中的元素用 Vector<string>。
Stack<Vector<string>> sv;
Vector<string> tmp; // 栈的元素,临时 Vector<string>容器。
// 第一个入栈的元素。
tmp[0] = "西施 1"; tmp[1] = "西施 2"; sv.push(tmp);
// 第二个入栈的元素。
tmp[0] = "西瓜 1"; tmp[1] = "西瓜 2"; sv.push(tmp);
// 第三个入栈的元素。
tmp[0] = " 冰 冰 1"; tmp[1] = " 冰 冰 2"; tmp[2] = " 冰 冰 3"; tmp[3] = " 冰 冰 4";
sv.push(tmp);
// 用嵌套的循环,把 sv 容器中的数据显示出来。
while (sv.isempty() == false)
{
sv.pop(tmp); // 出栈一个元素,放在临时容器中。
for (int ii = 0; ii < tmp.size(); ii++) // 遍历临时 Vector<string>容器,显示容器中每个
元素的值。
cout << " vs[" << ii << "] = " << tmp[ii] << endl;
}
// 创建 Vector 容器,容器中的元素用 Vector<string>。
Vector<Vector<string>> vv; // 递归使用模板类。
vv[0][0] = "西施 1"; vv[0][1] = "西施 2"; vv[0][2] = "西施 3";
vv[1][0] = "西瓜 1"; vv[1][1] = "西瓜 2";
vv[2][0] = "冰冰 1"; vv[2][1] = "冰冰 2"; vv[2][2] = "冰冰 3"; vv[2][3] = "冰冰 4";
// 用嵌套的循环,把 vv 容器中的数据显示出来。
for (int ii = 0; ii < vv.size(); ii++)
{
for (int jj = 0; jj < vv[ii].size(); jj++)
// cout << " vv[" << ii << "][" << jj << "] = " << vv[ii][jj] << endl;
cout << vv[ii][jj] << " ";
cout << endl;
}
}
154、模板类具体化
模板类具体化(特化、特例化)有两种:完全具体化和部分具体化。
语法请见示例程序。
具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。
具体化的模板类,成员函数类外实现的代码应该放在源文件中。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 类模板
template<class T1, class T2>
class AA { // 类模板。
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) :m_x(x), m_y(y) { cout << "类模板:构造函数。\n"; }
void show() const;
};
template<class T1, class T2>
void AA<T1, T2>::show() const { // 成员函数类外实现。
cout << "类模板:x = " << m_x << ", y = " << m_y << endl;
}
/
// 类模板完全具体化
template<>
class AA<int, string> {
public:
int m_x;
string m_y;
AA(const int x, const string y) :m_x(x), m_y(y) { cout << "完全具体化:构造函数。\n"; }
void show() const;
};
void AA<int, string>::show() const { // 成员函数类外实现。
cout << "完全具体化:x = " << m_x << ", y = " << m_y << endl;
}
/
// 类模板部分具体化
template<class T1>
class AA<T1, string> {
public:
T1 m_x;
string m_y;
AA(const T1 x, const string y) :m_x(x), m_y(y) { cout << "部分具体化:构造函数。\n"; }
void show() const;
};
template<class T1>
void AA<T1, string>::show() const { // 成员函数类外实现。
cout << "部分具体化:x = " << m_x << ", y = " << m_y << endl;
}
/
int main()
{
// 具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。
AA<int, string> aa1(8, "我是一只傻傻鸟。"); // 将使用完全具体化的类。
AA<char, string> aa2(8, "我是一只傻傻鸟。"); // 将使用部分具体化的类。
AA<int, double> aa3(8, 999999); // 将使用模板类。
}
156、模板类与继承
1)模板类继承普通类(常见)。
2)普通类继承模板类的实例化版本。
3)普通类继承模板类。(常见)
4)模板类继承模板类。
5)模板类继承模板参数给出的基类(不能是模板类)。
示例:
1)模板类继承普通类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
class AA // 普通类 AA。
{
public:
int m_a;
AA(int a) :m_a(a) { cout << "调用了 AA 的构造函数。\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
template<class T1, class T2>
class BB:public AA // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y,int a) : AA(a) , m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。
\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
int main()
{
BB<int, string> bb(8, "我是一只傻傻鸟。",3);
bb.func2();
bb.func1();
}
2)普通类继承模板类的实例化版本
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
class AA:public BB<int,string> // 普通类 AA。
{
public:
int m_a;
AA(int a,int x,string y) : BB(x,y),m_a(a) { cout << "调用了 AA 的构造函数。\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
int main()
{
AA aa(3,8, "我是一只傻傻鸟。");
aa.func1();
aa.func2();
}
3)普通类继承模板类。
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类 AA 变成了模板类,才能继承模板类。
{
public:
int m_a;
AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了 AA 的构造函数。
\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
int main()
{
AA<int,string> aa(3,8, "我是一只傻傻鸟。");
aa.func1();
aa.func2();
}
4)模板类继承模板类。
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类 AA 变成了模板类,才能继承模板类。
{
public:
int m_a;
AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了 AA 的构造函数。
\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
template<class T, class T1, class T2>
class CC :public BB<T1, T2> // 模板类继承模板类。
{
public:
T m_a;
CC(const T a, const T1 x, const T2 y) : BB<T1, T2>(x, y), m_a(a) { cout << "调用了 CC 的构
造函数。\n"; }
void func3() { cout << "调用了 func3()函数:m_a=" << m_a << endl;; }
};
int main()
{
CC<int,int,string> cc(3,8, "我是一只傻傻鸟。");
cc.func3();
cc.func2();
}
5)模板类继承模板参数给出的基类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
class AA {
public:
AA() { cout << "调用了 AA 的构造函数 AA()。\n"; }
AA(int a) { cout << "调用了 AA 的构造函数 AA(int a)。\n"; }
};
class BB {
public:
BB() { cout << "调用了 BB 的构造函数 BB()。\n"; }
BB(int a) { cout << "调用了 BB 的构造函数 BB(int a)。\n"; }
};
class CC {
public:
CC() { cout << "调用了 CC 的构造函数 CC()。\n"; }
CC(int a) { cout << "调用了 CC 的构造函数 CC(int a)。\n"; }
};
template<class T>
class DD {
public:
DD() { cout << "调用了 DD 的构造函数 DD()。\n"; }
DD(int a) { cout << "调用了 DD 的构造函数 DD(int a)。\n"; }
};
template<class T>
class EE : public T { // 模板类继承模板参数给出的基类。
public:
EE() :T() { cout << "调用了 EE 的构造函数 EE()。\n"; }
EE(int a) :T(a) { cout << "调用了 EE 的构造函数 EE(int a)。\n"; }
};
int main()
{
EE<AA> ea1; // AA 作为基类。
EE<BB> eb1; // BB 作为基类。
EE<CC> ec1; // CC 作为基类。
EE<DD<int>> ed1; // EE<int>作为基类。
// EE<DD> ed1; // DD 作为基类,错误。
}
157、模板类与函数
模板类可以用于函数的参数和返回值,有三种形式:
1)普通函数,参数和返回值是模板类的实例化版本。
2)函数模板,参数和返回值是某种的模板类。
3)函数模板,参数和返回值是任意类型(支持普通类和模板类和其它类型)。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA // 模板类 AA。
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
void show() const { cout << "show() x = " << m_x << ", y = " << m_y << endl; }
};
// 采用普通函数,参数和返回值是模板类 AA 的实例化版本。
AA<int, string> func(AA<int, string>& aa)
{
aa.show();
cout << "调用了 func(AA<int, string> &aa)函数。\n";
return aa;
}
// 函数模板,参数和返回值是的模板类 AA。
template <typename T1,typename T2>
AA<T1, T2> func(AA<T1, T2>& aa)
{
aa.show();
cout << "调用了 func(AA<T1, T2> &aa)函数。\n";
return aa;
}
// 函数模板,参数和返回值是任意类型。
template <typename T>
T func(T &aa)
{
aa.show();
cout << "调用了 func(AA<T> &aa)函数。\n";
return aa;
}
int main()
{
AA<int, string> aa(3, "我是一只傻傻鸟。");
func(aa);
}
158、模板类与友元
模板类的友元函数有三类:
1)非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数。
2)约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
3)非约束模板友元:模板类实例化时,如果实例化了 n 个类,也会实例化 n 个友元函数,每个实例
化的类都拥有 n 个友元函数。
1)非模板友元示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA
{
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
// 非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数,只能在类内实现。
friend void show(const AA<T1, T2>& a)
{
cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
}
/* friend void show(const AA<int, string>& a);
friend void show(const AA<char, string>& a);*/
};
//void show(const AA<int, string>& a)
//{
// cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
//
//void show(const AA<char, string>& a)
//{
// cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
show(a);
AA<char, string> b(88, "我是一只傻傻鸟。");
show(b);
}
2)约束模板友元示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
template <typename T>
void show(T& a); // 第一步:在模板类的定
义前面,声明友元函数模板。
template<class T1, class T2>
class AA // 模板类 AA。
{
friend void show<>(AA<T1, T2>& a); // 第二步:在模板类中,再次声明友元函
数模板。
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template<class T1, class T2>
class BB // 模板类 BB。
{
friend void show<>(BB<T1, T2>& a); // 第二步:在模板类中,再次声明友元函数
模板。
T1 m_x;
T2 m_y;
public:
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template <typename T> // 第三步:友元函数模板的定义。
void show(T& a)
{
cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <> // 第三步:具体化版本。
void show(AA<int, string>& a)
{
cout << "具体 AA<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <> // 第三步:具体化版本。
void show(BB<int, string>& a)
{
cout << "具体 BB<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
int main()
{
AA<int, string> a1(88, "我是一只傻傻鸟。");
show(a1); // 将使用具体化的版本。
AA<char, string> a2(88, "我是一只傻傻鸟。");
show(a2); // 将使用通用的版本。
BB<int, string> b1(88, "我是一只傻傻鸟。");
show(b1); // 将使用具体化的版本。
BB<char, string> b2(88, "我是一只傻傻鸟。");
show(b2); // 将使用通用的版本。
}
3)非约束模板友元
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 非类模板约束的友元函数,实例化后,每个函数都是每个每个类的友元。
template<class T1, class T2>
class AA
{
template <typename T> friend void show(T& a); // 把函数模板设置为友元。
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template <typename T> void show(T& a) // 通用的函数模板。
{
cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <>void show(AA<int, string>& a) // 函数模板的具体版本。
{
cout << "具体<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
show(a); // 将使用具体化的版本。
AA<char, string> b(88, "我是一只傻傻鸟。");
show(b); // 将使用通用的版本。
}
159、成员模板类
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA // 类模板 AA。
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) : m_x(x), m_y(y) {}
void show() { cout << "m_x=" << m_x << ",m_y=" << m_y << endl; }
template<class T>
class BB
{
public:
T m_a;
T1 m_b;
BB() {}
void show();
};
BB<string> m_bb;
template<typename T>
void show(T tt);
};
template<class T1, class T2>
template<class T>
void AA<T1,T2>::BB<T>::show() {
cout << "m_a=" << m_a << ",m_b=" << m_b << endl;
}
template<class T1, class T2>
template<typename T>
void AA<T1,T2>::show(T tt) {
cout << "tt=" << tt << endl;
cout << "m_x=" << m_x << ",m_y=" << m_y << endl;
m_bb.show();
}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
a.show();
a.m_bb.m_a = "我有一只小小鸟。";
a.m_bb.show();
a.show("你是一只什么鸟?");
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux终端简单配置(Vim、oh-my-zsh和Terminator)

文章目录 0. 概述1. 完整Vim配置2. Vim配置方案解释2.1 状态行与配色方案2.2 文件管理与缓存设置2.3 搜索与导航优化2.4 缩进与格式化设置2.5 粘贴模式快捷切换2.6 文件编码与格式2.7 性能优化 3. 安装 Oh My Zsh 及配置3.1 安装 Oh My Zsh3.2 Oh My Zsh 配置 3. Terminator终端…

vscode +STM32 VS CODE EXTENSION

stm32 vs code extersion 1.0.0版本可以直接导入cubeide的工程&#xff0c;之后版本不可以&#xff0c;所以为了省事&#xff0c;使用stm32 vs code extersion 1.0.0插件。 安装完stm32 vs code extersion插件&#xff0c;会默认把相关插件一起安装。但是需要手动安装Ninja&am…

交叉编译概念

交叉编译概念 目录 交叉编译概念1. 什么是交叉编译2. 交叉编译的作用3. 交叉编译器4. 交叉编译工具链5. 交叉编译的一般步骤6. 交叉编译实例 1. 什么是交叉编译 交叉编译是指在一个平台上编译代码&#xff0c;使其能够在另一个不同的平台上运行的过程。这种编译方式通常用于开…

Android12——Launcher3文件夹布局修改调整

文章声明&#xff1a;本文是笔者参考良心大佬作品后结合实际需求进行相应的定制&#xff0c;本篇主要是笔者记录一次解析bug笔记&#xff0c;文中可能会引用大佬文章中的部分图片在此声明&#xff0c;并非盈利目的&#xff0c;如涉嫌侵权请私信&#xff0c;谢谢&#xff01; 大…

果蔬识别系统性能优化之路

目录 一级目录二级目录三级目录 前情提要当前问题 优化方案1. 内存化2. 原生化3. 接口化 行动实现结语 一级目录 二级目录 三级目录 前情提要 超详细前端AI蔬菜水果生鲜识别应用优化之路 当前问题 indexddb在webview中确实性能有限&#xff0c;存储量上来后每次读取数据…

【机器学习】交通勘测

交通勘测 交通勘测中的关键应用场景 交通勘测中常用的数据来源 交通勘测中的挑战 结论 &#x1f388;边走、边悟&#x1f388;迟早会好 机器学习在交通勘测中的应用非常广泛&#xff0c;可以用于交通流量预测、事故检测、车辆分类、道路拥堵管理等多个方面。通过结合传感…

什么是函数调用约定?

目录 前言 一、函数调用约定的主要内容 二、常见的函数调用约定 1. __cdecl&#xff08;C Declaration&#xff09; 2. __stdcall&#xff08;Standard Call&#xff09; 3. __fastcall&#xff08;Fast Call&#xff09; 4. __thiscall&#xff08;This Call&#xff0…

【Spring Boot 3】【Web】国际化

【Spring Boot 3】【Web】国际化 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或…

[数据集][目标检测]轮胎检测数据集VOC+YOLO格式4629张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4629 标注数量(xml文件个数)&#xff1a;4629 标注数量(txt文件个数)&#xff1a;4629 标注…

【SQL】删除表中重复数据的方法

很久之前我写入一张sql的数据表&#xff0c;它里面有很多重复的内容。然后我想只保留一条原始数据&#xff1a; 例如上面的时间&#xff0c;出现了很多重复值。 我最初用的是这种方法&#xff1a; SELECT * FROM table_name WHERE primary_key IN (SELECT max(primary_key)F…

ubuntu20.04 colmap安装

apt-get update apt-get install colmap 官方包网址&#xff1a; colmap_3.6really3.6-1_amd64.deb Debian 11 Download (pkgs.org) 官方安装非常简单&#xff0c;但是看网上都是手动安装教程&#xff0c;都麻烦的要命&#xff01;我也踩了两天雷&#xff0c;还是看github上…

仕考网:公务员笔试和面试哪个难?

公务员笔试和面试哪个难?二者之间考察的方向不同&#xff0c;难度也是不同的。 笔试部分因其广泛的知识点和有限的考试时间显得难度更高一些&#xff0c;在笔试环节中&#xff0c;考生需在有限的时间内应对各种问题&#xff0c;而且同时还要面对激烈的竞争&#xff0c;在众多…

Java的内存泄漏和性能瓶颈

内存泄漏 ‌内存泄漏‌指的是程序中已分配的内存由于某种原因无法被释放或回收&#xff0c;导致内存的浪费和潜在的程序崩溃。在Java中&#xff0c;由于有垃圾回收机制&#xff08;GC&#xff09;&#xff0c;直接的内存泄漏相对较少&#xff0c;但间接的内存泄漏仍然可能发生…

栈栈栈专题

一、基础 Leetcode 3174. 清除数字 class Solution { public:string clearDigits(string s) {string st; // 用string模拟栈的行为for(auto& v: s){if(isdigit(v)) st.pop_back();else st v;}return st;} }; 二、进阶 三、邻项消除 四、合法括号字符串 五、…

每日一题——第八十题

题目&#xff1a;输入十个整数&#xff0c;将其中最小的数与第一个数交换&#xff0c;将最大的数与最后一个数对调 #include <stdio.h> void swap(int *a, int *b) { int temp *a; *a *b; *b temp; } int main() { int numbers[10]; int i; int minIndex …

50Kg大载重长航时油电混动多旋翼无人机技术详解

50Kg大载重长航时油电混动多旋翼无人机技术是一项高度复杂且前沿的研究领域&#xff0c;它结合了燃油发动机的高能量密度和电动机的高效性&#xff0c;旨在提高无人机的续航能力和载重能力。以下是对该技术的详细解析&#xff1a; 产品轴距&#xff1a;2320mm 产品尺寸&#x…

数仓建模—维度建模之维度表

数仓建模—维度建模之维度表 维度表(Dimension Table)是数据仓库中描述业务过程中各种维度信息的表,用于提供上下文和描述性信息,以丰富事实数据的分析 维度表是维度建模的灵魂所在,在维度表设计中碰到的问题(比如维度变化、维度层次、维度一致性、维度整合和拆分等)都…

Django+Vue家居全屋定制系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 需要的环境3.2 Django接口层3.3 实体类3.4 config.ini3.5 启动类3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质创作者&…

今年读过最绝的大模型神书死磕这本大模型神书!看完直接脱胎换骨!!

书名&#x1f4d6;&#xff1a;《大语言模型&#xff1a;基础与前沿》 该书深入阐述了大语言模型&#xff08;Large Language Model, LLM&#xff09;的基本概念和算法、研究前沿以及应用&#xff0c;内容全面且系统性强&#xff0c;适合&#x1f468;&#x1f3fb;‍&#x1…

踩坑记录-20240904--qt

1&#xff1a;请求接口没有数据 &#xff0c;请把本地的接口缓存清空&#xff0c;确保接口是从网络中拿数据 拿不到数据的情况下 接口判断是否从缓存中拿去数据也是false的情况 2&#xff1a;异步请求嵌套异步请求 要注意延时性的问题 因为第二个异步请求结束的时候 前面异步…