【C++初阶】之类和对象(下)

【C++初阶】之类和对象(下)

  • ✍ 再谈构造函数
    • 🏄 初始化列表的引入
      • 💘 初始化列表的语法
      • 💘 初始化列表初始化元素的顺序
    • 🏄 explicit关键字
  • ✍ Static成员
    • 🏄 C语言中的静态变量
    • 🏄 C++中的静态成员
    • 🏄 特性
  • ✍ 友元
    • 🏄 友元函数
    • 🏄 友元类
      • 💘 友元类的特性
  • ✍ 内部类
    • 🏄 内部类的特性
  • ✍ 匿名对象
  • ✍ 拷贝对象时的一些编译器优化
    • 🏄 隐式类型,连续的构造+拷贝构造->优化为直接构造
      • 💘 隐式类型生成的对象具有常性
    • 🏄 一个表达式中,连续的构造+拷贝构造->优化为一个构造
    • 🏄 一个表达式中,连续的拷贝构造+拷贝构造->优化一个拷贝构造
    • 🏄 一个表达式中,连续的拷贝构造+赋值重载->无法优化
    • 🏄 Release下不是一个表达式的连续的构造+拷贝构造-->构造函数(部分会优化)
  • ✍ 再次理解类和对象
    • 🏄 类和对象的理解
    • 🏄 类的组成

📃博客主页: 小镇敲码人
💞热门专栏:C++初阶
🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏
🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎
❤️ 什么?你问我答案,少年你看,下一个十年又来了 💞 💞 💞

前言:本篇博客接上篇类和对象中。接着来跟着博主学习C++类和对象下的一些特性吧!

✍ 再谈构造函数

构造函数体类的操作我们只能叫做赋值,不能叫做初始化,因为初始化只有一次,而赋值可以在构造函数体类无数次。

假设现在我们的类里面有const成员和引用成员,会发生什么情况呢?

在这里插入图片描述
奇怪这里我们明明在构造函数内给year和month赋值了呀,为什么还是会报错呢?报错说我们没有初始化,说明初始化并不发生在构造函数内。

我们来回顾一下,const对象和引用必须在定义的时候就初始化:

在这里插入图片描述
但是在类里面它们只是声明了一下而已,并没有定义,真正定义是在那个类实例化一个对象之后。而且const对象和引用在初始化之后就不能修改了,这样你应该就可以理解,为什么不允许在构造函数体类初始化这些对象了,因为我无法判断你是否第二次又对它进行了初始化(如果真那样做就逻辑不自洽了)。

🏄 初始化列表的引入

那不能在构造函数函数体里面初始化在哪里初始化呢?答案是在初始化列表里面初始化。

💘 初始化列表的语法

class Date
{
public:Date(int month_):year(3),month(month_),day(2){}
private:const int year;int& month;int day ;
};

在原先的普通构造函数的函数名后面加上冒号,然后对应的成员变量后面加括号,括号里面是其要初始化的值,不同变量间使用逗号分隔。

注意如果是const对象或者引用类型的初始化必须走初始化列表,拷贝构造函数也可以用来创建一个对象,这些类型也必须走初始化列表,否则就会报错。

在这里插入图片描述

这里就算我们使用了初始化列表,编译器隐式生成的拷贝赋值函数也会被删除。

在这里插入图片描述
除了const和引用类型的变量必须走初始化列表,没有无参的构造函数的自定义类型也必须走初始化列表(因为要给它传参数),也不能放在构造函数中,因为自定义类型的构造函数只能在初始化的时候调用。

有无参的构造函数(可以访问)的自定义类型会在定义的时候自动调用:

在这里插入图片描述
没有无参的构造函数时,如果你不再初始化列表里调用,就会报错:

在这里插入图片描述
这个时候我们应该在定义的时候给这个自定义类型传一个参数:

在这里插入图片描述

💘 初始化列表初始化元素的顺序

这个顺序与我们实际在初始化列表中的元素初始化顺序无关,只与元素的声明顺序有关。

在这里插入图片描述
在这里插入图片描述

🏄 explicit关键字

explicit关键字可以防止只需要传一个参数(只有一个或者后面都是缺省参数)的普通的构造函数发生隐式类型的转换。

请看下面代码:

class Date
{
public:Date(int year_){year = year_;month = 3;day = 2;}~Date(){}
private:int year;int month;int day ;
};int main()
{Date y(2023);y = 2022;return 0;
}

你是否会认为其会导致编译错误呢,其实不然,这里编译器会将2022隐式类型转化为Date类型,我们可以通过调试发现其确实调用了构造函数:

在这里插入图片描述

并且y的year变成了2022,这里是先调用了一次构造函数,再去调用了编译器默认生成的赋值构造函数。

在这里插入图片描述

如果我们在普通构造函数前加上explicit就不支持隐式类型转换了。

在这里插入图片描述

✍ Static成员

🏄 C语言中的静态变量

我们在C语言里面也有Static类型的变量,我们把它称作静态成员变量,这个变量有一个特征,就算出了函数作用域,它不会销毁,生命周期只有程序结束它才会结束。

void f()
{static int a = 3;int b = 3;a++;b++;
}
int main()
{f();f();return 0;
}

连续调用两次f()函数a为多少呢?

在这里插入图片描述

可以看到a变成了5,说明a执行了两次++,在第一次出函数后,它没有销毁,并且静态变量只会定义一次。

🏄 C++中的静态成员

在c++的类里面也会有静态的成员,它和C语言中的函数中的静态变量有什么区别和相同之处呢呢?

C++类里面有两类静态成员,它们是静态成员函数和静态成员变量。

class Date
{Date(){count++;}Date(const Date& x){count++;}static int Getcount(){return count;}~Date(){count--;}
private:static int count;
};int Date::count = 0;int main()
{return 0;
}

上述程序可以用来计算类实例化了多少个对象。下面外面来具体阐述一下它们的特性。

🏄 特性

  1. 静态成员函数和静态成员变量也受访问限定符的限制。
  2. 静态成员变量必须要在类外面初始化,初始化不要求访问限定符为public,但是下次调用的时候需要它在类外面可以访问,且不能多次初始化。
    在这里插入图片描述
  3. 静态成员变量不能在声明的时候给缺省值,因为它的初始化不走初始化列表,而是在类外面通过类名+::进行访问并初始化。

在这里插入图片描述
4、静态成员函数和静态成员变量在类外面访问(假设是公有的),可以通过实例化对象访问或者是类名+::访问。

在这里插入图片描述
5. 静态成员(变量和函数)为所有类对象所共享,不属于某个具体的对象,存放在静态区。
6. 静态成员函数类没有this指针,不能访问任何非静态成员,但是可以访问静态成员。

在这里插入图片描述
7. 但是非静态的成员函数可以调用静态成员。

在这里插入图片描述

想一想为什么需要静态函数呢?就拿刚刚计算实例化了多少对象的程序来说,想知道没有实例化对象时count为多少,如何知道呢?此时不能实例化对象且count为private,就只能借助于类的静态成员函数来完成。

✍ 友元

友元提供了一种突破访问限定符和类域限定符的作用,但是破坏了程序的耦合度,不易过多使用,友元分为友元函数友元类

🏄 友元函数

如果一个函数是一个类的友元函数,那么它就可以访问这个类的私有成员。

友元函数是为了解决重载<<函数,但是this指针默认在第一个参数的情况,我们应该让cout在第一个参数的位置,因为运算符重载函数的操作数和运算符重载函数的参数是一一对应的。
这里我们用代码来分析:

class Date
{
public:Date(){year = 2022;month = 2;day = 1;}void operator<<(std::ostream& cout){}
private:int year;int month;int day;
};int main()
{Date x;std::cout << x;
}

由于左操作数是cout,但是类的成员函数的默认第一个参数是this指针,所以这里会报错。cout的类型是ostream
在这里插入图片描述

我们可以使用友元函数解决这个问题;

class Date
{
public:friend std::ostream& operator<<(std::ostream& cout_, const Date& x);Date(){year = 2022;month = 2;day = 1;}private:int year;int month;int day;
};std::ostream& operator<<(std::ostream& cout_, const Date& x)
{cout_ << x.year << " " << x.month <<  " " << x.day << std::endl;return cout_;
}int main()
{Date x;std::cout << x << std::endl;return 0;
}

运行结果:

在这里插入图片描述

这里我们流提取函数之所以要返回cout_,是为了支持连续的调用这个函数。
std::cout << x << std::endl;,这段代码理解就是,先去调用operator<<(std::ostream& cout_, const Date& x),返回一个cout_,就变成了std::cout << std::endl;,继续调用流提取重载函数。流插入函数是同样的道理。

  • 友元函数只需要在相应的类里面声明一个函数(不受访问限定符的限定),并在函数前面加上friend关键词就可以了。注意你不能把友元函数的定义写在类里面,因为它不是类的成员。

在这里插入图片描述

  • 友元函数不能用const修饰,因为它并不是类的成员函数。
  • 一个函数可以是多个类的友元函数。

🏄 友元类

友元类是指的是,假设现在有两个类,A、B,如果你声明了A是B的友元类,在A中如果创建了B的实例化对象,就可以调用B的私有成员(私有变量和函数)。

下面我们用代码来验证一下:

// 定义一个名为B的类  
class B  
{  // 声明类A为B的友元类,这样A可以访问B的私有和保护成员  friend class A;  public:  // 公共成员函数ff,可以在类的外部调用  void ff()  {  // 函数体为空,没有实际功能  }  private:  // 在类的私有部分不能声明友元类,友元声明应该放在类的公有或保护部分  // 私有成员函数f,只能在B类内部或B的友元中调用  void f()  {  // 函数体为空,没有实际功能  }  // 私有整型成员变量a,初始化为3  int a = 3;  // 私有整型成员变量b,初始化为4  int b = 4;  
};  // 定义一个名为A的类  
class A  
{  
public:  // 公共成员函数fff,可以在类的外部调用  void fff()  {  // 调用B类对象x的公共成员函数ff  x.ff();  // 调用B类对象x的私有成员函数f  // 由于A是B的友元类,所以可以访问B的私有成员  x.f();  }  private:  // A类中含有一个B类的对象x作为私有成员  B x;  
};  int main()  
{  // 创建A类的对象y  A y;  // 程序正常结束,返回0  return 0;  
}

这段代码是没有问题的,从中我们可以发现友元类的一些特性。

💘 友元类的特性

  1. A是B的友元类,但是B不是A的友元类,友元关系是单向的。
  2. A是B的友元类,B是C的友元类,但是A不是C的友元类,友元关系是不能传递的。
  3. 声明友元类和声明友元函数的区别是类名前面多了classfriend class A;
  4. 友元类的声明可以在这个类的任何位置。

在这里插入图片描述

✍ 内部类

内部类就是在一个类的里面创建了一个类,但是这个类是独立的和外部类没有任何的关系(但是受它的访问限定符的限制,如果是private,在外面无法实例化对象),它也不属于外部类,不能通过外部类的this指针访问内部类的任何成员。外部类对内部类没有任何优越的访问权限。
但是内部类是外部类的友元类,访问外部类有优越的访问权限

下面一段代码帮助你理解内部类:

#include <iostream> // 引入标准输入输出库,用于使用std::cout  class A  
{  
public:  // A类的构造函数  A()  {  // 构造函数体为空  }  // A类的公有成员函数f  void f()  {  // 函数体为空  }  // A类的内部类B  class B  {  public:  // B类的公有成员函数f,接收一个A类的引用作为参数  void f(A& x)  {  // 输出A类对象的c成员变量和B类的静态成员变量count  std::cout << x.c << " " << count;  // 调用A类对象的公有成员函数f  x.f();  // 尝试调用A类对象的成员函数ff,但ff是A类的私有成员函数,这里会导致编译错误  x.ff();  }  private:  // B类的私有整型成员变量b,初始化为3  int b = 3;  };  private:  // A类的私有成员函数ff  void ff()  {  // 函数体为空  }  // A类的静态整型成员变量count,用于在多个A类对象间共享数据  static int count;  // A类的私有整型成员变量c,初始化为3  int c = 3;  
};  // 初始化A类的静态成员变量count,赋值为3  
int A::count = 3;  int main()  
{  // 创建A类的内部类B的对象b  A::B b;  // 创建A类的对象a  A a;  // 调用B类对象b的公有成员函数f,并传入A类对象a的引用  b.f(a);  // 程序正常结束,返回0  return 0;  
}

🏄 内部类的特性

  1. 创建内部类的实例化对象必须要使用外部类的类名+::.
  2. 内部类不能直接在类里面创建外部类的对象,要从外面传一个过来,外部类的成员通过传过来的对象访问,静态成员可以直接访问。

在这里插入图片描述

  1. sizeof()计算外部类的大小,和内部类没有任何关系。

在这里插入图片描述

在这里插入图片描述
这里也进一步验证了静态变量是放在静态区的,没有和类的普通成员变量存放在一起,也不算在类的大小里面。

局部的const变量是存在栈上的:

在这里插入图片描述
运行结果:

在这里插入图片描述

全局的const变量放在常量区。

  1. 内部类可以定义在外部类的public、protected、private都是可以的。但是它受外部类类域的限制。如果使用private,在外面就无法实例化内部类的对象了。

在这里插入图片描述

✍ 匿名对象

匿名对象就是没有名字的对象(是这个对象没有名字,不是这个类没有名字)。

我们写一段代码来举个例子:


class Date
{
public:Date(){std::cout << "Date()" << std::endl;}~Date(){std::cout << "~Date()" << std::endl;}
private:int year;int month;int day;
};int main()
{Date x;Date ();return 0;
}

在这里插入图片描述

Date ()就是一个匿名对象,但是它的作用域只有一行,出了这一行它就调用析构函数销毁了。

在这里插入图片描述

匿名对象的一些优势:

class Date
{
public:Date(){std::cout << "Date()" << std::endl;}Date(const Date& x){}~Date(){std::cout << "~Date()" << std::endl;}
private:int year;int month;int day;
};int main()
{Date y;Date x(y);Date z(Date ());return 0;
}

同样是使用一个类初始化另外一个类(调用拷贝构造函数),匿名对象可以不用给类取名字。

✍ 拷贝对象时的一些编译器优化

我们都知道C++里面有很多构造函数,但是有时候这些构造函数在一起的时候,编译器会省略一些没必要产生的构造,以达到优化的效果。主要优化是发生在传参和传返回值中。

🏄 隐式类型,连续的构造+拷贝构造->优化为直接构造

💘 隐式类型生成的对象具有常性

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(const Date& x)
{}
int main()
{f(3);return 0;
}

3–>Date会去调用普通构造函数,隐式类型转化为了Date类型,但是具有常性,如果不加const就会报错。

在这里插入图片描述
回归正题。请看下面一段代码:

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(Date x)
{}
int main()
{f(3);return 0;
}

这里调用f(3),正常应该是先构造函数,将3隐式类型转化为Date类型,然后再调用拷贝构造函数去初始化x,这里编译器做了优化,连续的构造+拷贝构造->优化为直接构造。

在这里插入图片描述

🏄 一个表达式中,连续的构造+拷贝构造->优化为一个构造

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(Date x)
{}
int main()
{f(Date(2022));return 0;
}

实际调用的构造函数:

在这里插入图片描述

如果不是一个表达式,会优化吗?

在这里插入图片描述
可以看到并没有优化。

🏄 一个表达式中,连续的拷贝构造+拷贝构造->优化一个拷贝构造

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(Date x)
{}Date f1()
{Date x(2022);return x;
}
int main()
{Date y = f1();return 0;
}

这里正常应该会调用一个普通的构造函数+两个拷贝构造函数,我们看实际的情况:

在这里插入图片描述

实际只调用一次拷贝构造函数,编译器优化了。

🏄 一个表达式中,连续的拷贝构造+赋值重载->无法优化

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(Date x)
{}Date f1()
{Date x(2022);return x;
}
int main()
{Date y(2023);y = f1();return 0;
}

这段代码正常应该是2个构造函数和1个赋值构造、1个拷贝构造函数,并且连续的拷贝构造和赋值构造在一个表达式中,能优化吗?我们拭目以待:

在这里插入图片描述

可以看到并没有优化。

🏄 Release下不是一个表达式的连续的构造+拷贝构造–>构造函数(部分会优化)

请看下面代码:

using namespace std;
class Date
{
public:Date(int year, int month = 2, int day = 1) ://普通的构造函数year_(year),month_(month),day_(day){cout << "Date(int year, int month = 2, int day = 1)" << endl;}Date(const Date& x) ://拷贝构造函数year_(x.year_),month_(x.month_),day_(x.day_){cout << "Date(const Date& x)" << endl;}Date& operator=(const Date& x)//拷贝赋值函数{year_ = x.year_;month_ = x.month_;day_ = x.day_;cout << "operator=(const Date& x)" << endl;return *this;}~Date()//析构函数{cout << "~Date" << endl;}
private:int year_;int month_;int day_;
};void f(Date x)
{}Date f1()
{Date x(2022);return x;
}
int main()
{f1();return 0;

Debug下的运行结果:

在这里插入图片描述

Release下的:

在这里插入图片描述

可以看到Release下的优化更猛。

✍ 再次理解类和对象

在这里插入图片描述
计算机是不认识我们现实世界中的实物的,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。

🏄 类和对象的理解

1、类和对象的理解
类:指的是对客观事物的一种描述,是对现实中一类具有共同属性和行为的事物的抽象

对象:指的是具体存在的事物,是能够看得到摸的着的真实存在的实体。

🏄 类的组成

而C++作为典型的面向对象的语言就使用类来描述现实世界中的事物,类分为属性行为两部分。属性是指的是类中的成员变量–>事物的特征,行为是指的是类中的一些方法函数–>事物能执行的操作。

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

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

相关文章

Leveled mode of TFHE

参考文献&#xff1a; [CGGI16] Chillotti I, Gama N, Georgieva M, et al. Faster fully homomorphic encryption: Bootstrapping in less than 0.1 seconds[C]//Advances in Cryptology–ASIACRYPT 2016: 22nd International Conference on the Theory and Application of C…

蓝桥杯嵌入式学习笔记(6):IIC程序设计

目录 前言 1. IIC基本原理 2. 电路原理 3. 代码编程 3.1 预备工作 3.2 AT24C02写读功能编写 3.2.1 AT24C02写操作实现 3.2.2 AT24C02读操作实现 3.3 MCP4017写读功能编写 3.3.1 MCP4017写操作实现 3.3.2 MCP4017读操作实现 3.4 main.c编写 3.4.1 头文件引用 3.4.…

蓝桥杯每日一题(floyd算法)

4074 铁路与公路 如果两个城市之间有铁路t11&#xff0c;公路就会t2>1,没铁路的时候t1>1,公路t21。也就是公路铁路永远都不会相等。我们只需要计算通过公路和铁路从1到n最大的那个即可。 floyd是直接在数组上更新距离。不需要新建dis数组。另外一定要记得把邻接矩阵初始…

【数据结构】链表习题之环形链表的约瑟夫问题

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 今天这道题目时牛客上的题目&#xff0c;名为环形链表的约瑟夫问题&#xff0c;很有趣的的一道题目 环形链表的约瑟…

SpringBoot在线电影订票系统实战开发教程及源码之手把手教你做一个在线电影订票系统(带参考论文)

今天发布的是一款基于SpringBoot脚手架开发的在线电影订票系统实战开发教程和完整源码&#xff0c;这里强调一下&#xff1a;本系统基于springboot脚手架开发&#xff0c;如果还没学习脚手架的话先去学习脚手架&#xff0c;不然学不懂这个电影订票系统哦&#xff0c;重要的事说…

2024河北石家庄矿业矿山展览会|河北智慧矿山展会|河北矿博会

2024中国&#xff08;石家庄&#xff09;国际矿业博览会      时间&#xff1a;2024年7月4-6日 地点&#xff1a;石家庄国际会展中心.正定      随着全球经济的持续增长和矿产资源需求的不断攀升&#xff0c;矿业行业正迎来前所未有的发展机遇。作为矿业领域的盛会&…

蓝桥OJ3510 冶炼金属(暴力+二分)

冶炼金属 学习了b站Turing_Sheep的思路 一、暴力模拟 思路&#xff1a; b[i] a[i] / v b[1] a[1] / v b[2] a[2] / v .... b[n] a[n] / v 以上列举中v要满足所有的记录&#xff0c;但凡一个记录不满足&#xff0c;v就不满足题意。 从小到大列举v,设置v最大为1e6 设置一个标…

如何用Flask中的Blueprints构建大型Web应用

本文分享自华为云社区《构建大型Web应用Flask中的Blueprints指南》&#xff0c;作者&#xff1a; 柠檬味拥抱。 什么是Blueprints&#xff1f; 什么是Blueprints&#xff1f; Blueprints是Flask中的一种模式&#xff0c;用于将应用程序分解为可重用的模块。每个蓝图实际上是…

时序数据库IoTDB:功能详解与行业应用

一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前&#xff0c;先了解一下何谓时序数据。 时序数据&#xff0c;也称为时间序列数据&#xff0c;是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…

蓝牙耳机哪个品牌的好?2024年精选硬核机型推荐

​随着时代的进步和潮流的演进&#xff0c;人们对蓝牙耳机的需求已不再局限于音质&#xff0c;舒适度也成为了关键考量。下面&#xff0c;我将为你推荐五款既舒适又性能出色的蓝牙耳机。 一、如何挑选蓝牙耳机&#xff1f;&#xff08;重点码住&#xff09; 1.选择知名大品牌&…

1.4.1 着色器

着色器&#xff08;Shader&#xff09;是运行在GPU上的小程序&#xff0c;这些小程序为图形渲染管线的某个特定部分而运行&#xff0c;从基本意义上来说&#xff0c;着色器只是一种把输入转化为输出的程序。 一、着色器类QOpenGLShaderProgram QOpenGLShaderProgram是Qt中对着…

C++ 迭代器与反向迭代器

目录 一&#xff0c;什么是迭代器 1&#xff0c;定义 2&#xff0c;迭代器的设计思维 3&#xff0c;迭代器种类 二&#xff0c;迭代器与容器 1&#xff0c;容器中的迭代器 2&#xff0c;迭代器失效问题 三&#xff0c;迭代器的类型萃取&#xff08;traits&#xff09; …

sdwan本地组网分析

随着数字化转型的深入发展&#xff0c;企业对网络架构的要求也不断提高。SDWAN&#xff08;软件定义广域网&#xff09;作为一种创新的网络技术&#xff0c;正在逐渐受到企业的关注和采用。SDWAN本地组网技术可以帮助企业快速搭建高效稳定的企业网络架构&#xff0c;提升企业的…

Linux:基础IO

回顾C文件接口 stdin & stdout & stderr C 默认会打开三个输入输出流&#xff0c;分别是 stdin, stdout, stderr 仔细观察发现&#xff0c;这三个流的类型都是 FILE*, fopen 返回值类型&#xff0c;文件指针 系统文件I/O 接口介绍 open man open #include <sy…

TSINGSEE青犀推出县域治理视频基座数字化、智慧化解决方案

一、方案背景 县域治理方案是我国地方治理体系的重要组成部分&#xff0c;对于促进县域经济社会发展、维护社会稳定、推进全面深化改革具有重要意义。随着科技的不断进步&#xff0c;视频监管已经成为了现代社会治理的重要手段之一。县域治理视频监管方案是通过视频监控、数据…

鸿蒙OS开发实例:【装饰器-@BuilderParam】

背景 这是一个基础概念&#xff0c;其实没有什么原因&#xff0c;练习过程中&#xff0c;自然可以感受到其用法&#xff0c;后期加上真实项目的演练&#xff0c;会形成习惯 功能核心理念 “在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法&#xff0c;将会…

电商系列之优惠券

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

安全上网,防止上网被记录(v2ray实现加密通信)

近期听一位亲威说&#xff0c;她在公司休闲的时候上了哪个网站&#xff0c;浏览了过的网站IT部门的人都会知道&#xff0c;这是因为现在大多数网络设备&#xff0c;像路由与交换机都有记录访问网站地址记录功能&#xff0c;涉及还可以设置成记录到交互的内容。要想保密&#xf…

MySQL面试汇总(一)

MySQL 如何定位慢查询 如何优化慢查询 索引及其底层实现 索引是一个数据结构&#xff0c;可以帮助MySQL高效获取数据。 聚簇索引和非聚簇索引 覆盖索引 索引创建原则 联合索引

Linux系统-----------MySQL 数据类型

目录 MySQL 数据类型 一、数值类型 二、日期和时间类型 三、字符串类型 &#xff08;1&#xff09;CHAR类型 &#xff08;2&#xff09;VARCHAR类型 &#xff08;3&#xff09;CHAR和VARACHAR的比较及其应用场景 MySQL 数据类型 MySQL 中定义数据字段的类型对你数据库的…