当前位置: 首页 > news >正文

【C++笔记】类和对象的深入理解(三)

【C++笔记】类和对象的深入理解(三)

🔥个人主页大白的编程日记

🔥专栏C++笔记


文章目录

  • 【C++笔记】类和对象的深入理解(三)
    • 前言
    • 一.日期类的实现
      • 1.1声明和定义分离
      • 1.2日期类+=整数
      • 1.3日期类+整数
      • 1.4日期类-=整数
      • 1.5日期类-日期
      • 1.6复用对比
      • 1.7日期类==日期类
      • 1.8日期类<日期类
      • 1.9比较复用
      • 1.10前置和后置
      • 1.11日期类-日期类
      • 1.12日期类IO
    • 二.取地址运算符重载
      • 2.1const成员函数
      • 2.2取地址运算符重载
    • 三.再探构造函数
    • 四.类型转换
    • 五.static成员
    • 六.友元
    • 七.内部类
    • 八.匿名对象
    • 后言

前言

哈喽,各位小伙伴大家好!上期我们讲了类和对象的更深入的内容。今天我们就给类和对象收尾。话不多说,咱们进入正题!向大厂冲锋!

一.日期类的实现

为了加深我们前面对类和对象的理解。我们现在来试着手搓一个日期类。

1.1声明和定义分离

我们想让.h放函数的声明。.cpp放函数的定义。

#pragma once#include<iostream>
using namespace std;
#include<assert.h>class Date
{friend istream& operator>>(istream& in, Date& d);friend ostream& operator<<(ostream& out, const Date& d);//友元声明
public:Date(int year ,int month ,int day );void Print();// Ĭinlineint GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return monthDayArray[month];}int GetYear();int GetMonth();int GetDay();bool operator<(const Date& d) const;bool operator<=(const Date& d) const;bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator==(const Date& d) const;bool operator!=(const Date& d) const;bool CheckDate();Date operator+(int day) const;Date& operator+=(int day);Date operator++(int);//后置Date& operator++();//前置Date operator--(int);//后置Date& operator--();//前置Date& operator-=(int day);Date operator-(int day) const;int operator-(const Date& d) const;
private:int _year;int _month;int _day;
};
istream& operator>>(istream& in,  Date& d);
ostream& operator<<(ostream& out, const Date& d);

我们日期类主要实现他的比较和日期类之间的相互运算。

1.2日期类+=整数

这里我们的思路是先将整数加到天数上。然后如果天数不超过当月天数。直接返回即可。否则说明日期比当月的所有日期都大。则向下月借位。天数减去当月天数之和,以此类推知道天数不超过当月的最大天数位置。如果12借位则年份+1,月份改为1即可。

int GetMonthDay(int year, int month)
{assert(month > 0 && month < 13);static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return monthDayArray[month];
}
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}

1.3日期类+整数

现在我们实现日期类+整数,也就是不改变日期类。返回日期类+=整数的结果。那我们可以复用日期类+=整数的逻辑。为了不修改日期类。我们对日期类拷贝一份tmp。让tmp进行+=的逻辑这样改变就不会日期类。

Date Date::operator+(int day) const
{Date tmp=*this;tmp +=day;return tmp;
}

1.4日期类-=整数

这里思路和我们前面实现+的思路一样。都是通过借位的思想。我们向当天数-day。
然后当天数!>0时,向上一个月借位,天数+=上个月的天数(注意是上个月的,因为当月的天数已经被减过了)。如果是1月的话,借去年12月的天数。让月份=12然后年份–。

Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){if (_month == 1){_month = 12;_day += GetMonthDay(--_year, _month);}else{_day += GetMonthDay(_year, --_month);}}return *this;
}

1.5日期类-日期

日期类-日期我们就复用-=即可。

Date Date::operator-(int day) const
{Date tmp=*this;tmp -= day;return tmp;
}

1.6复用对比

在这里插入图片描述

1.7日期类==日期类

判断两个日期类很简单。我们只需要判断是否他们的年月日都相等即可。

bool Date::operator==(const Date& d) const
{if (_year == d._year && _month == d._month && _day == d._day){return true;}else{return false;}
}

1.8日期类<日期类

判断两个日期类<。
先比较年。
<返回true。
==继续比较月。月<返回true。 ==返回比较天。
剩下的情况都是false的情况。直接返回false.

bool Date::operator<(const Date& d) const
{if (_year < d._year)//比较年{return true;}else if (_year == d._year)//年相等{if (_month < d._month)//判断月{return true;}else if (_month == d._month)//月相等{return _day < d._day; //判断天}}return false;//年不相等
}

1.9比较复用

剩下的我们通过前面实现的<和==复用即可。

bool Date::operator!=(const Date& d) const
{return !(*this == d);
}
bool Date::operator<=(const Date& d) const
{return *this < d || *this == d;
}
bool Date::operator>(const Date& d) const
{return !(*this < d)&&!(*this==d);
}
bool Date::operator>=(const Date& d) const
{return !(*this < d);
}

1.10前置和后置

前置我们拷贝一份*this,在复用+=或-=即可。

Date Date::operator++(int)
{Date tmp = *this;*this += 1;return tmp;
}
Date& Date::operator++()
{*this += 1;return *this;
}
Date Date::operator--(int)
{Date tmp=*this;*this-= 1;return tmp;
}
Date& Date::operator--()
{*this -= 1;return *this;
}

1.11日期类-日期类

两个日期类相减得出他们之间相差的天数。
我们的思路就是直接让小的天数一直相加,直到相加到小的日期和大的日期相等即可。每次日期++就用一个变量记录天数即可。

int Date::operator-(const Date& d) const
{int sum = 0;int flag = 1;Date max, min;max = *this;min = d;if (*this < d)//假设法{swap(max, min);flag = -1;}while (min!=max){sum++; min++;}sum *=flag;return sum;
}

1.12日期类IO

因为类的成员函数默认*this抢占了第一个位置。和我们平时的写法不一样。所以我们把日期类的输出和输出放在类外面。那放在类外面我们如何访问类的成员变量呢?那我们就可以加一个友元函数声明。

istream& operator>>(istream& in, Date& d)
{cout<<"请依次输入年月日:"<<endl;in >>d._year>> d._month >> d._day;return in;
}
ostream& operator<<(ostream& out, const Date& d)
{out << d._year <<"年" << d._month<<"月" << d._day<<"日";return out;
}

为了实现连续输入或输出。我们需要返回istrem或ostrem对象。

同时注意流对象不支持拷贝。所以istrem或ostrem必须用引用。

二.取地址运算符重载

2.1const成员函数

  • 定义
    将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。

  • const修饰
    const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。const 修饰Date类的Print成员函数,Print隐含的this指针由 Date* const this 变为const Date* const this。

    不写加const。

加上const。

同时非const成员也可以调用const成员函数。因为权限可以缩小。所以加上const可以防止我们的程序不小心篡改(原本不应该修改却不小心修改会报错),同时也让我们的的成员函数传参更宽泛,const成员也可以调用。所以能加尽加。

2.2取地址运算符重载

取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,⼀般这两个函数编译器自动生成的就可以够我们⽤了,不需要去显示实现。除非⼀些很特殊的场景,比如我们不想让别⼈取到当前类对象的地址,就可以自己实现⼀份,胡乱返回⼀个地址。

class Date
{
public:Date* operator&(){return this;// return nullptr;}const Date* operator&()const{return this;// return nullptr;}
private:int _year; // 年int _month; // ⽉int _day; // ⽇
};

一般这两个成员函数都不需要我们显示的写。因为他们两个是默认成员函数。

按理说我们只写const成员函数即可。因为不论是const成员还是非const成员都可以调用。但是const成员调用返回的是const this*。所以还需要写两份。并且编译器调用时会调用最匹配的。

三.再探构造函数

  • 初始化列表
    之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有⼀种方式,就是初始化列表,初始化列表的使用方式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后面跟⼀个放在括号中的初始值或表达式。

大概形式如下:

 Date(int& x, int year = 1, int month = 1, int day = 1):_year(year),_month(month),_day(day),_t(12),_ref(x),_n(1){// error C2512: “Time”: 没有合适的默认构造函数可⽤
// error C2530 : “Date::_ref” : 必须初始化引⽤
// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象 
}
  • 定义的位置
    每个成员变量在初始化列表中只能出现⼀次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。因为初始化列表是定义的地方所以,只能初始化一次。否则就会变成多次定义。

  • 定义初始化
    引用成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否则会编译报错。

class Time
{
public:Time(int hour=0):_hour(hour){cout << "Time()" << endl;}
private:int _hour;
};
class Date
{
public:Date(int& x,int year = 1, int month = 1, int day = 1):_year(year), _month(month), _day(day),a(1),_ref(x)//成员定义{// error C2512: “Time”: 没有合适的默认构造函数可⽤// error C2530 : “Date::_ref” : 必须初始化引⽤// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象}void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}
private://声明int _year;int _month;int _day; int main();int& _ref;const int a;Time _t;
};

引用成员变量,const成员变量必须在初始化列表初始化。因为他们必须在定义的地方初始化。

没有默认构造的类类型也必须在初始化列表初始化,因为他必须手动传参调用构造函数。
那初始化列表和函数体内赋值可以混着用吗?
可以,因为有些场景必须混着用。

Date(int& x,int year = 1, int month = 1, int day = 1):_year(year), _month(month), _day(day),a(1),_ref(x),_ptr((int*)malloc(size(int)//成员定义
{if (_ptr == nullptr){perror(malloc fail!);}
}

例如有个指针,我们malloc以后需要检查是否失败。那就必须在函数体内检查。

  • 缺省值
    C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的。
private://声明int _year=1;int _month=1;int _day=1; int* _ptr=((int*)malloc(sizeof(int)));

在声明的位置给一个缺省值。
在这里插入图片描述

  • 总结
    尽量使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显⽰在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的⾃定义类型成员会调⽤这个成员类型的默认构造函数,如果没有默认构造会编译错误。
    所以初始化列表能写尽写,因为就算你不写他也会走初始化列表。

  • 初始化顺序
    初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持⼀致。

大家看一下这道题选什么。

可能很多同学都会觉得选A。但实际不是这样的。因为初始化列表初始化的顺序是声明的顺序。

声明是顺序是他们在内存存放的顺序。初始化是按照内存中的顺序初始化。

四.类型转换

class A
{
public://构造函数explicit就不再⽀持隐式类型转换// explicit A(int a1)A(int a1):_a1(a1){}//explicit A(int a1, int a2)A(int a1, int a2):_a1(a1), _a2(a2){}void Print(){cout << _a1 << " " << _a2 << endl;}
private:int _a1 = 1;int _a2 = 2;
};
int main()
{// 1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3//编译器遇到连续构造+拷⻉构造->优化为直接构造A aa1 = 1;aa1.Print();const A& aa2 = 1;// C++11之后才⽀持多参数转化A aa3 = { 2,2 };return 0;
}
  • 隐式类型转化
    C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。

    这里我们可以验证一下。

这里报错是为啥?
因为隐式类型转化生成是临时对象,临时对象具有常性。所以要加上const引用。

那隐式类型转化有什么用?

class Stack
{
public:void Push(const A& aa){}
private:int top;
};
int main()
{Stack s;A aa = 1;s.Push(aa);s.Push(1);return 0;
}


可以发现隐式类型转化可以让我们写代码更加方便简洁。

  • explicit
    如果不想发生隐式类型转化, 构造函数前面加explicit就不再支持隐式类型转换。

五.static成员

  • 静态成员变量
    用static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化。
  • 共享
    静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。

  • 静态成员函数
    用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。

  • 访问权限
    静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。

  • 指定类域
    突破类域就可以访问静态成员,可以通过类名::静态成员或者对象.静态成员来访问静态成员变量和静态成员函数。

  • 访问限定符
    静态成员也是类的成员,受public、protected、private访问限定符的限制。

  • 缺省值
    静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。

  • 练习一
    题目:求1+2+3…+n

这道题目把常规的方法都限制了。但是这道题可以用我们的静态成员解决。
这道题主要修饰构造出循环这个条件。所以我们可以用一个类数组来构造这个条件。
定义一个n大小的类数组。那就会调用n次构造。我们只需要定义两个静态成员。然后每次构造把当前的值累加即可。

class Sum {public:Sum() {_ret += _i;++_i;}static int GetRet() {return _ret;}private:static int _i;static int _ret;
};
int Sum::_i = 1;
int Sum::_ret = 0;
class Solution {public:int Sum_Solution(int n) {//变⻓数组Sum arr[n];return Sum::GetRet();}
};

  • 练习二
C c;
int main()
{A a;B b;static D d;return 0;
}


六.友元

  • 定义
    友元提供了⼀种突破类访问限定符封装的方式,友元分为:友元函数和友元类,在函数声明或者类声明的前面加friend,并且把友元声明放到⼀个类的里面。
class A
{// 友元声明friend void func(const A& aa, const B& bb);
private:int _a1 = 1;int _a2 = 2;
};
void func(const A& aa, const B& bb){cout << aa._a1 << endl;cout << bb._b1 << endl;}

例如这里func是A的好朋友,func就可以访问A的成员。

  • 声明
    外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,他不是类的成员函数。

  • 声明位置
    友元函数可以在类定义的任何地方声明,不受类访问限定符限制。

  • 多个友元
    ⼀个函数可以是多个类的友元函数。

class A
{// 友元声明friend void func(const A& aa, const B& bb);
private:int _a1 = 1;int _a2 = 2;
};
class B
{// 友元声明friend void func(const A& aa, const B& bb);
private:int _b1 = 3;int _b2 = 4;
};

func既是A的友元又是B的友元。

  • 友元类
    友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员
class A
{// 友元声明friend class B;
private:int _a1 = 1;int _a2 = 2;
};
class B
{
public:void func1(const A& aa){cout << aa._a1 << endl;cout << _b1 << endl;}void func2(const A& aa){cout << aa._a2 << endl;cout << _b2 << endl;}
private:int _b1 = 3;int _b2 = 4;
};
int main()
{A aa;B bb;bb.func1(aa);bb.func1(aa);return 0;
}

B是A的友元类。B的所有成员函数都可以访问A的成员变量。

  • 单向性
    友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。

  • 传递性
    友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元。

  • 使用
    有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

七.内部类

  • 定义
    如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。
class A
{
private:static int _k;int _h = 1;
public:class B // B默认就是A的友元{public:void foo(const A& a){cout << _k << endl; //OKcout << a._h << endl; //OK}private:int _b;};
};
int A::_k = 1;
int main()
{cout << sizeof(A) << endl;A::B b;A aa;b.foo(aa);
}


所以刚刚OJ的代码也可以改成内部类

class Solution {// 内部类class Sum{public:Sum(){_ret += _i;++_i;}};static int _i;static int _ret;public:int Sum_Solution(int n) {// 变⻓数组Sum arr[n];return _ret;}
  • 默认友元
    内部类默认是外部类的友元类。
  • 封装
    内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地方都用不了。

八.匿名对象

  • 定义
    用类型(实参)定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参)定义出来的叫有名对象。

匿名对象让我们写代码更方便。

  • 生命周期
    匿名对象的生命周期只在当前⼀行,⼀般临时定义⼀个对象当前用⼀下即可,就可以定义匿名对象。

    可以看到未打印1之前,A就析构了。因为匿名对象声明周期只在当前行。

后言

这就是类和对象的深入理解。今天讲了很多内容。大家自己好好消化。感谢各位的耐心垂阅!咱们下期见!拜拜~

相关文章:

【C++笔记】类和对象的深入理解(三)

【C笔记】类和对象的深入理解(三) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(三)前言一.日期类的实现1.1声明和定义分离1.2日期类整数1.3日期类整数1.4日期类-整数1.5日期类-日期1.6复用对…...

时代变了,MySQL 早已不是最流行的数据库了

以下文章来源于古时的风筝 &#xff0c;作者风筝 在StackOverflow 上看到2024年技术趋势&#xff0c;关于数据库的部分&#xff0c;PostgreSQL 是开发人员使用最多的数据库&#xff0c;超过 MySQL 了。虽然在国内好像不是这样。 PostgreSQL 在 2018 年的开发者调查中首次亮相…...

K8S容器实例Pod安装curl-vim-telnet工具

在没有域名的情况下&#xff0c;有时候需要调试接口等需要此工具 安装curl、telnet、vim等 直接使用 apk add curlapk add vimapk add tennet...

代码随想录算法训练营DAY09之动态规划(一)基础题目

理论基础&#xff1a; 如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#xff0c;贪心没有状态推导&#xff0c;而是从局部直接选最优的。 例子&#xff1a; 例如&a…...

线性系统分析

一、定义 (1)叠加性 若 且 则称该系统具有叠加性。 叠加性:系统的一个输入不影响系统对其他输入的响应。 (2)均匀性 若 对任意常数a下式都成立 则称该系统具有均匀性。 均匀性:系统能够保持对输入信号的缩放因子不变。 (3)线性系统 若一个系统同时具有叠加性和…...

Ubuntu 20.04 部署 NET8 Web - Systemd 的方式 达到外网访问的目的

1.Ubuntu服务器环境安装 1.1 增加微软包安装源 wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb1.2 Install the .NET SDK # 更新本地软件包列表。原理&am…...

线程池(ThreadPool):使用ExecutorService、ThreadPoolExecutor等线程池管理并发任务以及底层实现原理

线程池&#xff08;ThreadPool&#xff09;是一种通过预先创建和维护一组线程的机制&#xff0c;用来高效管理并发任务。线程池不仅能减少创建和销毁线程的开销&#xff0c;还能更好地控制并发任务的执行。Java 中提供了多种方式来管理线程池&#xff0c;其中包括 ExecutorServ…...

人力资源数据集分析(二)_随机森林与逻辑回归

数据入口&#xff1a;人力资源分析数据集 - Heywhale.com 数据说明 字段说明EmpID唯一的员工IDAge年龄AgeGroup年龄组Attrition是否离职BusinessTravel出差&#xff1a;很少、频繁、不出差DailyRate日薪Department任职部门&#xff1a;研发部门、销售部门、人力资源部门Dista…...

【30天玩转python】数据库操作

数据库操作 数据库是应用程序中用于存储和管理数据的核心组件。Python 提供了多种与数据库交互的方式&#xff0c;支持不同类型的数据库&#xff0c;包括关系型数据库&#xff08;如 MySQL、PostgreSQL&#xff09;和 NoSQL 数据库&#xff08;如 MongoDB&#xff09;。在这篇…...

PTT:Point Tree Transformer for Point Cloud Registration 论文解读

目录 一、导言 二、相关工作 1、基于Transformer的点云配准 2、针对点云的局部注意力 三、PTT 1、KPconv提取特征 2、Tree Transformer Encoder 3、Decoder 4、估计姿态 5、损失函数 四、实验 1、对比不同Backbone 2、运行时间对比 3、对比不同PTT方法下RR指标的…...

C++速通LeetCode中等第7题-和为K的子数组(巧用前缀和)

巧用哈希表与前缀和&#xff0c;前缀和差为k的两个序号之间的数组就是满足条件的子数组&#xff0c;用哈希表来存放每个序号的前缀和。 前缀和就是头元素到当前序号子数组元素的和 class Solution { public:int subarraySum(vector<int>& nums, int k) {unordered_…...

【读书笔记-《30天自制操作系统》-23】Day24

本篇内容依然比较简单&#xff0c;主要是优化窗口功能以及开发定时器应用程序。首先是优化窗口的切换功能&#xff0c;实现通过键盘和鼠标切换窗口&#xff0c;然后是实现通过鼠标关闭窗口。接着实现不同窗口输入状态的切换&#xff0c;最后是实现定时器的API与应用程序。 1.…...

XML:DOM4j解析XML

XML简介&#xff1a; 什么是XML&#xff1a;XML 是独立于软件和硬件的信息传输工具。 XML 的设计宗旨是传输数据&#xff0c;而不是显示数据。XML 标签没有被预定义。您需要自行定义标签。XML不会做任何事情&#xff0c;XML被设计用来结构化、存储以及传输信息。 XML可以发明…...

15.5 创建监控控制平面的service

本节重点介绍 : k8s中service的作用和类型创建k8s控制平面的service 给prometheus采集用&#xff0c; 类型clusterIp kube-schedulerkube-controller-managerkube-etcd service的作用 Kubernetes Service定义了这样一种抽象&#xff1a; Service是一种可以访问 Pod逻辑分组…...

【Docker Nexus3】maven 私库

1.部署环境 window 11 x64Docker Desktop 4.34.1 (166053) Docker Engine v27.2.0 1.1.Docker 镜像源 1.1.1.Docker Engine 配置 {"builder": {"features": {"buildkit": true},"gc": {"defaultKeepStorage": "32…...

Docker本地部署Chatbot Ollama搭建AI聊天机器人并实现远程交互

文章目录 前言1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 前言 本文主要分享如何在群晖NAS本地部署并运行一个基于大语言模型Llama 2的个人本地聊天机器人并结合内网穿透工具…...

MySQL:用户管理

添加用户 create user usernamelocalhost identified by user_password;删除用户 drop user usernamelocalhost;查看所有用户 输入格式 select user,host from mysql.user; 输出 mysql> select user,host from mysql.user; ----------------------------- | user …...

论文《Mixture of Weak Strong Experts on Graphs》笔记

【Mowst 2024 ICLR】论文提出了一种新的图神经网络架构&#xff0c;称为Mixture of weak and strong experts&#xff08;Mowst&#xff09;&#xff0c;通过将轻量级的多层感知机&#xff08;MLP&#xff09;作为弱专家和现成的GNN作为强专家相结合&#xff0c;以处理图中的节…...

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解(3)】

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解&#xff08;3&#xff09;】 1、前言说明2、流程说明3、现场提交&#xff08;线下&#xff09;4、网上提交1-起诉书样例2-起诉书编写&#xff08;1&#xff09;原告信息&#xff1a;&…...

数据结构(Day14)

一、学习内容 结构体 概念 引入&#xff1a;定义整数赋值为10 int a10; 定义小数赋值为3.14 float b3.14; 定义5个整数并赋值 int arr[5] {1 , 2 , 3 , 4 ,5}; 定义一个学生并赋值学号姓名成绩 定义一个雪糕并赋值名称产地单价 问题&#xff1a;没有学生、雪糕 数据类型 解决&…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...