C++初阶:2_类与对象(下)

news2024/11/23 1:58:23

类与对象(下)

一.再谈构造函数

1. 构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

2. 初始化列表

(所有的成员变量会先走初始化列表,再走函数体)

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式(括号里可以写参数,全局变量,常量也可以调用函数)

class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

8afe85f7f4ed312cac2463950c07c70

能用初始化列表就建议用初始化列表

一般初始化列表和函数体只写一个,两个同时写也可以

【注意】

  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

  2. 类中包含以下成员,必须放在初始化列表位置进行初始化:

  • 引用成员变量

  • const成员变量

  • 自定义类型成员(且该类没有默认构造函数时)

    其他成员, 可以在初始化列表, 也可以函数体内; 但是建议在初始化处理

class A
{
public:
A(int a)
	:_a(a)
{}
private:
int _a;
};
class B
{
public:
B(int a, int ref)
	:_aobj(a)
	, _ref(ref)
	, _n(10)
{}
private:
A _aobj;  // 没有默认构造函数
int& _ref;  // 引用
const int _n; // const 
};
  1. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
class Time
{
public:
Time(int hour = 0)
	:_hour(hour)
{
	cout << "Time()" << endl;
}
private:
int _hour;
};
class Date
{
public:
Date(int day)
{}
private:
int _day;
Time _t;
};
int main()
{
Date d(1);
}
  1. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}

	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};
int main() {
	A aa(1);
	aa.Print();
}
A.输出1  1
B.程序崩溃
C.编译不通过
D.输出1  随机值
答案:D

dee5f023a675dcd02bb5fbde4fa5501

【补充】

  1. 缺省值给法

    02dd348c45de9b198d863fbc52693f3

  2. 单参数函数的构造

    • 不同对象之间赋值中间会产生临时变量

      0259dee39665b7081c567d194287d93

  3. 可以直接 = 构造的优势

    e078f0338bf8804ed935fc4c31d68e8

    6b50cc3f04c2c344c2ce08d46b34257

  4. 不想让隐式类型转换发生

    ----在构造函数前加explicit

    d61972b9d5dcdba4da91187b6ae0656

  5. 多参数的 = 构造

    • c++98不支持多参数
    • c++11支持
    class A
    {
    public:
    	A(int a1,int a2)
    		:_a1(a1)
    		,_a2(a2)
    	{}
    private:
    	int _a1;
    	int _a2;
    };
    
    int main()
    {
    	//c++11
    	A aa1 = { 1,2 };
    	const A& aa2 = { 1,2 };
    	return 0;
    }
    

3. explicit关键字

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。

class Date
{
public:
	// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用
	// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译
	explicit Date(int year)
		:_year(year)
	{}

	/*
	// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转换作用
	// explicit修饰构造函数,禁止类型转换
	explicit Date(int year, int month = 1, int day = 1)
	: _year(year)
	, _month(month)
	, _day(day)
	{}
	*/

	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

void Test()
{
	Date d1(2022);
	// 用一个整形变量给日期类型对象赋值
	// 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值
	d1 = 2023;
	// 将1屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,禁止了单参构造函数类型转换的作用
}

上述代码可读性不是很好,用explicit修饰构造函数,将会禁止构造函数的隐式转换。

二.static成员

1. 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

面试题:实现一个类,计算程序中创建出了多少个类对象。

class A
{
public:
	A() { ++_scount; }
	A(const A& t) { ++_scount; }
	~A() { --_scount; }
	static int GetACount() { return _scount; }
private:
	/*声明*/static int _scount;//不能在这给缺省值
};
/*定义*/int A::_scount = 0;
void TestA()
{
	cout << A::GetACount() << endl;
	A a1, a2;
	A a3(a1);
	cout << A::GetACount() << endl;
}

2. 特性

  1. 静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区
  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
  3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  4. 静态成员函数没有隐藏的this指针不能访问任何非静态成员
  5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制
  6. 静态成员函数的目的只要一个就是为了访问静态成员变量

【问题】

  1. 静态成员函数可以调用非静态成员函数吗?不可以
  2. 非静态成员函数可以调用类的静态成员函数吗?可以

三.友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

友元分为:友元函数友元类

1. 友元函数

问题:现在尝试去重载operator<<,然后发现没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator<<重载成全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用
	// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧
	ostream& operator<<(ostream& _cout)
	{
		_cout << _year << "-" << _month << "-" << _day << endl;
		return _cout;
	}
private:
	int _year;
	int _month;
	int _day;
};

友元函数可以直接访问类的私有成员,它是定义在类外部普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}
int main()
{
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}

说明:

  • 友元函数可访问类的私有和保护成员,但不是类的成员函数
  • 友元函数不能用const修饰(没有this指针)
  • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同

2. 友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

  • 友元关系是单向的,不具有交换性。
    比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递
  • 如果C是B的友元, B是A的友元,则不能说明C时A的友元。
  • 友元关系不能继承,在继承位置再给大家详细介绍。
class Time
{
	friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		: _hour(hour)
		, _minute(minute)
		, _second(second)
	{}

private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	void SetTimeOfDate(int hour, int minute, int second)
	{
		// 直接访问时间类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

四.内部类

概念:**如果一个类定义在另一个类的内部,这个内部类就叫做内部类。**内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。(可以理解成一个全局类定义到类里面收到类域和访问限定符的限制,并且是外面这个类的友元类)

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

特性:

  1. 内部类可以定义在外部类的public、protected、private都是可以的。
  2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
  3. sizeof(外部类)=外部类,和内部类没有任何关系。
class A
{
private:
	static int k;
	int h;
public:
	class B // B天生就是A的友元
	{
	public:
		void foo(const A& a)
		{
			cout << k << endl;//OK
			cout << a.h << endl;//OK
		}
	};
};
int A::k = 1;
int main()
{
	A::B b;
	b.foo(A());

	return 0;
}

de966da970a7086e379a03aef60c635

五.匿名对象

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution {
public:
	int Sum_Solution(int n) {
		//...
		return n;
	}
};
int main()
{
	A aa1;
	// 不能这么定义对象,因为编译器无法识别下面是一个函数声明,还是对象定义
	//A aa1();
	// 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字,
	// 但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数
	A();
	A aa2(2);
	// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说
	Solution().Sum_Solution(10);
	return 0;
}

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

在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的。

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{
			_a = aa._a;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
void f1(A aa)
{}
A f2()
{
	A aa;
	return aa;
}
int main()
{
	// 传值传参
	A aa1;
	f1(aa1);
	cout << endl;
	// 传值返回
	f2();
	cout << endl;
	// 隐式类型,连续构造+拷贝构造->优化为直接构造
	f1(1);
	// 一个表达式中,连续构造+拷贝构造->优化为一个构造
	f1(A(2));
	cout << endl;
	// 一个表达式中,连续拷贝构造+拷贝构造->优化一个拷贝构造
	A aa2 = f2();
	cout << endl;
	// 一个表达式中,连续拷贝构造+赋值重载->无法优化
	aa1 = f2();
	cout << endl;
	return 0;
}

9fb6d9158f606d3df854e037a1c0110

七.再次理解类和对象

现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。比如想要让计算机认识洗衣机,就需要:

  1. 用户先要对现实中洗衣机实体进行抽象—即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程

  2. 经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、Java、Python等)将洗衣机用类来进行描述,并输入到计算机中

  3. 经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。

  4. 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。

在类和对象阶段,大家一定要体会到,类是对某一类实体(对象)来进行描述的,描述该对象具有那些属性,那些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。

image-20240327192846190

八.练习题

  1. 求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句

    法一:

    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 a[n];
            return Sum::GetRet();
        }
    };
    

    法二:

    class Solution {
    private:
        class Sum
        {
        public:
            Sum()
            {
                _ret+=_i;
                _i++;
            }
        };
    
    public:
        int Sum_Solution(int n) {
            Sum a[n];
            return _ret;
        }
    private:
        static int _i;
        static int _ret;
    };
    
    int Solution::_i=1;
    int Solution::_ret=0;
    
  2. 计算日期到天数的转换

    #include <iostream>
    using namespace std;
    
    class Date
    {
    public:
        friend istream& operator>>(istream& in,Date& d)
        {
            in>>d._year>>d._month>>d._day;
            return in;
        } 
    
        int GetMonthDay(int year,int month)
        {
            static int monthDays [13]={ 0,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 monthDays[month];
        }
    
        int GetDays()
        {
            int days=0;
            int flag=0;
            while(_month!=0)
            {
                if(flag==0)
                {
                    days+=_day;
                    flag=1;
                }
                else
                {
                    days+=GetMonthDay(_year, _month);
                }
                _month--;
            }
            return days;
        }
    
    private:
        int _year;
        int _month;
        int _day;
    
    };
    
    int main() {
        Date d;
        cin>>d;
        cout<<d.GetDays();
    }
    // 64 位输出请用 printf("%lld")
    
  3. 日期差值OJ链接

    #include <iostream>
    using namespace std;
    
    class Date
    {
    public:
        Date(int year, int month, int day)
            :_year(year)
            , _month(month)
            , _day(day)
        {}
    
        int GetMonthDay(int year, int month)
        {
            static int monthdays[13] = { 0,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 monthdays[month];
        }
    
        bool operator<(const Date& d)const
        {
            if (_year < d._year || (_year == d._year && _month < d._month) || (_year == d._year && _month == d._month && _day < d._day))
            {
                return true;
            }
            return false;
        }
    
        Date& operator+=(int day)
        {
            _day += day;
            if (_day > GetMonthDay(_year, _month))
            {
                _day -= GetMonthDay(_year, _month);
                _month++;
                if (_month == 13)
                {
                    _month = 1;
                    _year++;
                }
            }
            return *this;
        }
    
        Date& operator++()
        {
            *this += 1;
            return *this;
        }
    
        int operator-(const Date& d)const
        {
            Date max = *this;
            Date min = d;
            if (max < min)
            {
                min = *this;
                max = d;
            }
            int n = 0;
            while (min < max)
            {
                ++min;
                ++n;
            }
            return n + 1;
        }
    private:
        int _year;
        int _month;
        int _day;
    };
    
    int main() {
        int year1, month1, day1;
        int year2, month2, day2;
    
        scanf("%04d%02d%02d", &year1, &month1, &day1);
        Date d1(year1, month1, day1);
        scanf("%04d%02d%02d", &year2, &month2, &day2);
        Date d2(year2, month2, day2);
        cout << d1 - d2;
    }
    // 64 位输出请用 printf("%lld")
    
  4. 打印日期OJ链接

    #include<iostream>
    using namespace std;
    
    class Date
    {
    public:
        Date(int year, int month = 1, int day = 1)
        {
            _year = year;
            _month = month;
            _day = day;
        }
        Date(const Date& d)
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        friend istream& operator>>(istream& in, Date& d)
        {
            in >> d._year >> d._month >> d._day;
            return in;
        }
    
        Date& operator+=(int day)
        {
            _day+=day;
            while (_day > GetMonthDay(_year, _month))
            {
                _day -= GetMonthDay(_year, _month);
                _month++;
                if (_month == 13)
                {
                    _month = 1;
                    _year++;
                }
            }
            return *this;
        }
    
        Date& operator-=(int day)
        {
            _day -= day;
            while (_day < 0)
            {
                _month--;
                if (_month == 0)
                {
                    _month = 12;
                    _year--;
                }
                _day += GetMonthDay(_year, _month);
            }
            return *this;
        }
    
        //前置++
        Date& operator++()
        {
            *this += 1;
            return *this;
        }
    
        //前置--
        Date& operator--()
        {
            *this -= 1;
            return *this;
        }
    
    
        int GetMonthDay(int year, int month)
        {
            static int monthDays[13] = { 0,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 monthDays[month];
        }
    
        int GetDays()
        {
            int days = 0;
            int flag = 0;
            Date tmp = (*this);
    
            while (tmp._month != 0)
            {
                if (flag == 0)
                {
                    days += tmp._day;
                    flag = 1;
                }
                else
                {
                    days += GetMonthDay(tmp._year, tmp._month);
                }
                tmp._month--;
            }
            return days;
        }
    
    
        void WhichDay(int n)
        {
            while (n != GetDays())
            {
                ++(*this);
            }
        }
    
        void Print()
        {
            printf("%04d-%02d-%02d\n",_year,_month,_day);
        }
    
    private:
        int _year;
        int _month;
        int _day;
    
    };
    
    int main() {
        int m, n;
        while (cin >> m >> n) {
            Date d1(m);
            d1.WhichDay(n);
            d1.Print();
        }
    }
    // 64 位输出请用 printf("%lld")
    
  5. 累加天数OJ链接

    #include <iostream>
    using namespace std;
    class Date
    {
    public:
        Date(int year,int month,int day)
        :_year(year)
        ,_month(month)
        ,_day(day)
        {}
    
        int GetMonthDay(int year,int month)
        {
            static int monthdays[13]={0,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 monthdays[month];
        }
    
        Date& operator+(int day)
        {
            _day+=day;
            while(_day>GetMonthDay(_year,_month))
            {
                _day-=GetMonthDay(_year,_month);
                _month++;
                if(_month==13)
                {
                    _month=1;
                    _year++;
                }
            }
            return *this;
        }
    
        void Print()
        {
            printf("%04d-%02d-%02d\n",_year,_month,_day);
        }
    private:
        int _year;
        int _month;
        int _day;
    };
    
    
    
    int main() {
        int m;
        int days, year,month,day;
        cin>>m;
        for(int i=0;i<m;i++)
        {
            cin >> year >> month >> day >> days;
            Date d1(year,month,day);
            d1=d1+days;
            d1.Print();
        }
    
    
        return 0;
    }
    // 64 位输出请用 printf("%lld")
    

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

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

相关文章

Kubernetes容器平台下的 GPU 集群算力管控

引言 随着最近一两年生成式大模型的迭代出新&#xff0c;尤其是以 ChartGPT 为代表的大语言模型&#xff0c;几乎一夜间让所有人都看到了人工智能改变世界的潜力。而作为持续发力 GPU 通用计算&#xff08;CUDA&#xff09;的 AI 专业显卡提供商&#xff0c;Nvidia 公司成为了…

人大金仓数据库介绍与使用指南

人大金仓数据库是一款强大的关系型数据库管理系统&#xff0c;具有简单易用、高性能和稳定可靠的特点。本文将介绍人大金仓数据库的安装方法、常用的SQL语法以及相关工具的使用。 一、安装方法&#xff1a; 1、下载人大金仓数据库安装程序&#xff1b; 2、运行安装程序&#…

事件穿透效果

讲述一下事件穿透的需求&#xff0c;大家可以根据实际情况来考虑是否采用这种方式来制作页面&#xff0c;&#xff08;项目中遇到了底部是地图&#xff0c;两侧面板&#xff0c;但是UI在设计的时候为了好看&#xff0c;会有很大的遮罩阴影部分&#xff0c;如果按照时间制作会导…

pip永久修改镜像地址

修改命令&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ 效果&#xff1a; 会在C:\Users\PC(用户名)\AppData\Roaming\pip目录下新增或修改文件pip.ini 文件内容&#xff1a; [global] index-url https://pypi.tuna.tsinghua.e…

关于柔性阵列(/三维阵列)波束形成的仿真实践以及稳健波束形成的思考(1)

说明 关于波束形成&#xff0c;我之前写过几篇相关的博文&#xff0c;如参考资料[1]、[2]、[3]。除去在博文[2]中有讨论过阵元相对位置关系对波束形成的影响&#xff1a;“如何基于遗传算法优化阵元相对位置关系以压低旁瓣峰值”以外&#xff0c;似乎我认知里的天线阵列&#x…

PS从入门到精通视频各类教程整理全集,包含素材、作业等

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 【Photoshop 教程】史上最容易听懂的PS...在最后四…

k8s入门到实战(十四)—— Helm详细介绍及使用

Helm 使用 Helm 是一个 k8s 应用的包管理工具&#xff0c;类似于 Ubuntu 的 APT 和 CentOS 中的 YUM。 Helm 使用 chart 来封装 k8s 应用的 yaml 文件&#xff0c;我们只需要设置自己的参数&#xff0c;就可以实现自动化的快速部署应用。 Helm 通过打包的方式&#xff0c;支…

谭浩强第五版C语言课后习题(编程题)+答案

谭浩强第五版作为初学C语言必读的一本教材&#xff0c;课后习题具有非常大的参考价值&#xff0c;也是很多高校期末考试或者考研的重要参考。在这里我整理了一部分个人认为比较重要的编程题&#xff0c;供大家作参考 1.输入两个数&#xff0c;求他们的最大公约数和最小公倍数&…

Cesium.js综合实验

Cesium.js综合实验 1 概述 Cesium是一个跨平台、跨浏览器的展示三维地球和地图的开源 JavaScript 库&#xff0c;是AGI公司计算机图形开发小组与2011年研发的三维地球和地图可视化开源JavaScript库&#xff0c;Cesium一词来源于化学元素铯&#xff0c;铯是制造原子钟的关键元…

VUE+ elementUI 表头动态渲染的两种方法

效果&#xff1a; <template><div><el-alert title"比较麻烦的写法" type"error"></el-alert><el-table border style"width:300px;" :data"tabelData"><el-table-columnv-for"column in colum…

如何在群晖NAS搭建bitwarden密码管理软件并实现无公网IP远程访问

前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊如何在群晖NAS搭建bitwarden密码管理软件并实现无公网IP远程访问&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&am…

访问学者如何申请国外信用卡?

作为一名访问学者&#xff0c;如果你计划在国外长期居住或短期停留&#xff0c;并希望申请国外信用卡&#xff0c;这可能是一个相当实用的工具。国外信用卡不仅可以帮助你在海外购物和旅行时更加便利&#xff0c;还能建立起你在国际金融体系中的信用记录&#xff0c;为未来的金…

鼠标不动了怎么办?鼠标不能移动解决方法

鼠标不能移动有可能是鼠标坏了&#xff0c;或者是电脑的软件和硬件有冲突等原因造成。最近有小伙伴就咨询了有关鼠标的问题&#xff0c;昨天鼠标还能使用&#xff0c;不知道为什么今天就突然不能用了。那么我们在排除鼠标坏掉了的情况下&#xff0c;试试对鼠标进行修复吧。下面…

请你记住这3款国产软件,免费又实用,它们值得收藏

闲话不多说&#xff0c;直上干货。 1、坚果云 坚果云是一款极具良心的网盘软件&#xff0c;其免费版本同样无广告干扰&#xff0c;界面设计简约大气&#xff0c;在文件上传与下载速度上&#xff0c;坚果云完全不限速&#xff0c;这一点远超其他同类产品。 用户可以在手机、电…

粗略总结AI大模型学习需要了解的要点

目录 一、概念简介 二、兴起原因 三、相关要点 四、不足之处 五、总结 一、概念简介 AI大模型学习是指利用大规模数据集和强大计算能力进行深度学习模型的训练。随着数据的爆炸式增长和计算资源的提升&#xff0c;AI大模型学习成为了现代人工智能研究的重要方向。 二、兴起…

徽宇阀门现已加入2024第13届生物发酵展会

参展企业介绍 温州徽宇阀门有限公司是专业生产高精度不锈钢过滤器设备及卫生级阀门、管道、管件及泵等系列产品。秉承严谨、实用的作风,所有产品均选用高品质的原材料。公司对产品品质的要求没有止境,生产全部采用CNC等国际一流的数控加工中心设备&#xff0c;所有产品均按照IS…

Linux系统使用Docker部署Portainer结合内网穿透实现远程管理容器和镜像

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

VR全景赋能智慧农业,打造沉浸式种植体验平台

随着人口的增长&#xff0c;传统农业也正在面临着不一样的挑战&#xff0c;加上很多人对农业的固有印象&#xff0c;很少有年轻人愿意下到农田里&#xff0c;那么该如何提高产量、降低成本以及引导年轻人深刻感受现代农业成为了急需解决的问题。 随着城市化脚步的推进&#xff…

代码随想录笔记|C++数据结构与算法学习笔记-栈和队列(〇)|stack、queue、单调队列和优先队列(priority_queue)、大顶堆和小顶堆

文章目录 stack容器stack 基本概念常用接口构造函数赋值操作数据存取大小操作 queue容器queue常用接口构造函数&#xff1a;赋值操作数据存取大小操作 单调队列优先队列大顶堆小顶堆 stack容器 stack 基本概念 栈中只有顶端的元素才可以被外界使用&#xff0c;因此栈不允许有遍…

ubuntu22.04安装dnsmasq最详细易懂

安装 准确的来说&#xff0c;不是安装&#xff0c;因为默认ubuntu22版本自带的有dnsmasq&#xff0c;所以我们不用下载了&#xff0c;直接使用即可&#xff0c;否则就会产生冲突&#xff0c;这块吃了大亏。 最好在root账户下操作&#xff0c;没有设置root密码的&#xff0c;可…