lesson3-C++类和对象(下)

news2024/11/24 4:01:02

个人主页:Lei宝啊 

愿所有美好如期而遇


目录

再谈构造函数

构造函数体赋值

初始化列表

explicit关键字

Static成员

概念

特性

友元

友元函数

友元类

内部类

匿名对象

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

再次理解封装

练习题


再谈构造函数

构造函数体赋值

class Date
{

public:
	Date(int year = 2023, int month = 10, int day = 30)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;

};

我们通过构造函数可以给对象赋值,但是不能称为初始化,因为初始化只能初始化一次,而构造函数函数体中可以进行多次赋值。

初始化列表

class Date
{

public:
	Date(int year = 2023, int month = 10, int day = 30)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

private:
	int _year;
	int _month;
	int _day;

};
初始化列表:以一个冒号开始 ,接着是一个以 逗号分隔的数据成员列表 ,每个 " 成员变量 "后面跟
一个放在括号中的初始值或表达式。
下面的大括号里还可以进行一系列赋值或者其他操作,相当于是构造。

注意: 

  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)。
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
  • 引用成员变量
  • const成员变量
  • 自定义类型成员(且该类没有默认构造函数时)

class A
{

public:
	A(int a = 0)
		:_a(a)
	{}

private:
	int _a;
	int _b;

};

class B
{

public:
	B(int& a,int b,A& c)
		:_a(a)
		,_b(b)
		,_c(c)
	{}

private:
	int& _a;
	const int _b;
	A _c;

};

int main()
{

	int a = 6;
	int b = 3;
	A c;

	B b(a,b,c);

	return 0;
}
  • f具有常属性,不可修改。
  • 引用在声明时就需要初始化,而且之后不可以修改。
  • 自定义类型在没有默认构造函数的时候,我们有没有给参数,或者说他在类里声明,我们都需要把他加进初始化列表中进行初始化。
3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。
其实也就是不管是内置类型还是自定义类型,都会先去调用他的默认构造或者构造函数,在进入构造函数前,先走初始化列表,不管我们是否写了初始化。
class A
{

public:
	A(int num = 0)
		:_a(num)
	{}

	A(const A& _A)
	{
		_a = _A._a;
		_b = _A._b;
	}

	int Getnum_a()
	{
		return _a;
	}

private:
	int _a;
	int _b;
};

int main()
{

	//会先去调用默认构造函数,然后在构造之前走初始化列表
	//将a._a初始化为0
	A a;
	cout << a.Getnum_a() << endl;

	return 0;
}
4. 成员变量 在类中 声明次序 就是其在初始化列表中的 初始化顺序,与其在初始化列表中的先后
次序无关
class A
{

public:
    
    //这里初始化顺序不是按先写就先初始化    
    //而是按照声明顺序进行初始化
	A(int a)
		:_a2(a)
		,_a1(_a2)
	{}

	void print() const
	{
		cout << _a1 << " " << _a2 << endl;
	}

private:
	int _a1;
	int _a2;

};

int main()
{

	A a(1);
	a.print();


	return 0;
}

explicit关键字

构造函数不仅可以构造与初始化对象,对于单个参数或者多个参数的构造函数,还可以通过赋值类型转换的方式构造对象。
解释在代码注释里
class Date
{

public:
	Date(int year)
		:_year(year)
	{}

	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

	void print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;

};

int main()
{

    //C++支持单个参数的构造函数这样使用
	//先用2023去构造临时对象,该临时对象再进行和对象b的拷贝构造
	Date date1 = 2023;
	date1.print();
    
    //C++11支持多参数这样使用,和上面是相同的道理
	Date date2 = { 2023,10,30 };
	date2.print();

	return 0;
}

class Date
{

public:
	Date(int year)
		:_year(year)
	{}

	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	void print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;

};

int main()
{

	Date date1 = 2023;
	date1.print();

	Date date2 = { 2023,10,30 };
	date2.print();
	
	const Date date3 = { 2023,10,31 };
	date3.print();

	return 0;
}

但是这样写可读性不好,有没有看着别扭的感觉,所以如果我们不想让这样的方式能通过编译,就使用explicit关键字修饰该构造函数。

class Date
{

public:
	explicit Date(int year)
		:_year(year)
	{}

	explicit Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	void print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;

};

int main()
{

	Date date1 = 2023;
	date1.print();

	Date date2 = { 2023,10,30 };
	date2.print();

    //用这三个数去构造一个临时对象,然后拷贝构造
	const Date date3 = { 2023,10,31 };
	date3.print();

	return 0;
}

加上explicit后就不允许这样构造对象了。

我们再举一个其他栗子:

class Date
{

public:
	Date(int year,int month,int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		cout << "Date()" << endl;
	}
	
private:
	int _year;
	int _month;
	int _day;

};

int main()
{

	const Date& a = { 2023,11,2 };

	return 0;
}

解释:我们用三个参数去构造一个临时对象,a就是这个临时变量的别名,如果我们不加const就会报错,因为临时变量具有常性,而我们先前说过权限放大和缩小的问题,一个const类型的对象被非const类型引用,会出现权限放大,所以我们要加上const。

Static成员

我们先来抛出一个问题,假如我们想要计算一共有几个对象被构造,那么如何计算?我们有如下几个方案,判断他们的可行性。

方案一:搞一个全局变量,在每一次的调用构造函数时++。

方案二:在类里定义一个计数的变量。

接下来我们来看他们是否可行:

先看方案一实现的代码:

#include <iostream>
using namespace std;

int count = 0;

class A
{
public :
	A()
		:_a(1)
		,_b(2)
	{
		count++;
	}

	void print() const
	{
		cout << _a << " " << _b << endl;
 	}

private:
	int _a;
	int _b;

};

void func(A a)
{
	//...
}

int main()
{

	A a;
	func(a);

	return 0;
}

结果不明确是因为我们使用了using namespce std;展开了该命名空间,而该命名空间里有函数的名字也叫做count,所以就出现了结果不明确,当然,我们可以换个名字,不是非要用count,而且,我不展开std命名空间不可以吗,我只展开部分,比如cout或者endl展开就好,难道不可以吗?是的,都可以。

接着看方案二:

class A
{
public:
	A()
		:_a(1)
		, _b(2)
	{
		count++;
	}

	void print() const
	{
		cout << _a << " " << _b << endl;
	}

private:
	int _a;
	int _b;
	int count;

};

void func(A a)
{
	//...
}

int main()
{

	A a;
	func(a);

	return 0;
}

这样可以吗?显然不行,每个对象都有count,这样的话,不管哪个count,都只是1,都只构造一次。

那么有没有更好的解决方案呢?有的,就是我们接下来要说的static成员。

概念

  • 声明为static的类成员称为类的静态成员。
  • static修饰的成员变量,称之为静态成员变量;
  • 用static修饰的成员函数,称之为静态成员函数
  • 静态成员变量一定要在类外进行初始化。
实现一个类,计算程序中创建出了多少个类对象。
class A
{

public:
	A()
	{
		_count++;
	}

	A(const A& a)
	{
		_count++;
	}

	static int Get_count()
	{
		return _count;
	}


private:
	static int _count;

};

//这里才是_count的定义
int A::_count = 0;

void func(A a)
{
	//...
}

int main()
{

	A a;
	A b(a);
	func(a);

	cout << A::Get_count() << endl;

	return 0;
}

结果为3。

特性

  • 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区,所以在使用时要加作用域限定符,比如:A::Get_count()
  • 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明,比如:int A::_count = 0;
  • 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  • 静态成员函数没有隐藏的this指针,不能访问任何非静态成员.
  • 静态成员也是类的成员,受publicprotectedprivate 访问限定符的限制

友元

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

友元函数

我们现在可以去尝试重载operator<<运算符重载了。

如果我们将这个重载写在类体内,那么必然会有this指针去占到参数的第一个位置,那么我们再调用cout时流插入流入的方向就变成流向对象了,看例子:

#include <iostream>
using namespace std;

class Date
{

public:

	Date(int year = 2023, int month = 11, int day = 2)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print()
	{
		cout << _year << "-" << _month << "_" << _day << endl;
	}

	ostream& operator<<(ostream& out)
	{
		out << _year << "-" << _month << "-" << _day;

		return out;
	}

private:
	int _year;
	int _month;
	int _day;

};


int main()
{
	Date a;

	a << cout;

}

这样重载<<运算符是不是很别扭,非常奇怪,所以注定了我们要将他重载到类外,也就是全局,

那么我们将其写在全局后,又因为这几个成员变量都是私有的,我们在类外无法访问到,我们当然可以写他们的Get函数得到他们的值,但是这样比较麻烦,而且C++不喜欢这样做,java才喜欢,C++会去搞一个友元函数。

直接看用法。

#include <iostream>
using namespace std;

class Date
{
    
    //在函数前加friend表示是友元函数,虽然我们将其声明在类内,但这个函数不属于类
	friend ostream& operator<<(ostream& out, const Date& d);

public:

	Date(int year = 2023, int month = 11, int day = 2)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print()
	{
		cout << _year << "-" << _month << "_" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;

};

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "-" << d._month << "_" << d._day << endl;
	return out;
}

int main()
{
	Date a;

	cout << a;

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

这样我们重载的函数成为了Date类的友元函数,就可以访问Date私有的成员变量。

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
我们举例说明,看代码:
#include <iostream>
using namespace std;

class Date
{

	friend class Time;

public:

	Date(int year = 2023, int month = 11, int day = 2)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print() const
	{
		cout << _year << "-" << _month << "_" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;

};

class Time
{

public:
	Time(int hour = 11, int minute = 54, int second = 0)
		:_hour(hour)
		,_minute(minute)
		,_second(second)
	{}
	
	void Print_Date_Time() const
	{
		cout << _d._year << "-" << _d._month << "-" << _d._day;
		cout << ":";
		//cout << _hour << "-" << _minute << "-" << _second << endl;

		printf("%d-%d-%02d\n", _hour, _minute, _second);
	}

private:
	int _hour;
	int _minute;
	int _second;

	Date _d;
};

int main()
{

	Time t;
	t.Print_Date_Time();

}

我们要注意Time是Date的友元,Time可以访问Date的私有的成员变量,但是Date不能访问Time私有的成员变量,有句话说的好,我把你当朋友,但是你不一定把我当朋友,就是这个道理。

内部类

首先说明C++中很少使用内部类,java是喜欢使用内部类的,我们只需要明白他的语法,能够看懂,明白需要注意的地方就好,很少使用内部类。

#include <iostream>
using namespace std;

class A
{

public:
	A()
	{
		_count++;
	}

	A(const A& a)
	{
		_count++;
	}

	static int Get_count()
	{
		return _count;
	}

	class B
	{
	public:
		B()
		{
            _count++;
			_a = 3;
		}

	private:
		int _a;
	};


private:
	int _A;
	static int _count;

};

int A::_count = 0;

int main()
{

	cout << sizeof(A) << endl;

	return 0;
}

我们可以看到计算A的大小时不包括B,可以这么理解,B是一个独立的类,只是受到A的访问限定符的限制,并且B天生就是A的友元,可以访问A的私有变量。

两个点:

  • A,B是独立的两个类,只是B受到A访问限定符的限制。
  • B天生就是A的友元。

其余不再多说。

匿名对象

直接看示例:

#include <iostream>
using namespace std;

class A
{

public:
	A()
	{
		_count++;
	}

	A(const A& a)
	{
		_count++;
	}

	static int Get_count()
	{
		return _count;
	}

	class B
	{
	public:
		B()
		{
			_count++;
			_a = 3;
		}

	private:
		int _a;
	};


private:
	int _A;
	static int _count;

};

int A::_count = 0;

int main()
{

	cout << sizeof(A) << endl;

    //匿名对象调用成员函数
	cout << A().Get_count() << endl;

	return 0;
}

匿名对象就是没有名字的对象,生命周期只在本行。语法就是类名加括号表示匿名对象。

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

class Date
{

public:

	Date(int year = 2023, int month = 11, int day = 3)
		:_year(year)
		, _month(month)
		, _day(day)
		,count(0)
	{
		_count++;
		count = _count;
		cout << "构造-" << count << endl;
	}

	Date(const Date& a)
		:count(0)
	{
		_count++;
		count = _count;
		cout << "拷贝构造-" << count << endl;
	}

	~Date()
	{
		cout << "析构-" << count << endl;
	}

	Date& operator=(const Date& a)
	{
		cout << "赋值" << endl;
		return *this;
	}

private:
	int _year;
	int _month;
	int _day;

	int count;
	static int _count;
};

int Date::_count = 0;

void func(Date aa)
{
	
}

Date func()
{
	Date a;
	return a;
}

接下来我们来写测试用例:

测试用例一:

int main()
{

	Date a;
	a = 1;

	return 0;
}

首先是a构造,接着临时对象构造,临时对象赋值给a,临时对象生命周期只在本行,临时对象析构,主函数结束a析构。


int main()
{
	
	//隐式类型转换,首先是1先构造一个临时对象,接着是
	//临时对象拷贝构造a
	Date a = 1;

	return 0;
}

所以这就是编译器的优化,将构造加拷贝构造优化为--->构造,只有在一行上编译器才会优化。

而且只有比较新的编译器才会这么去优化,老版本的编译器是不会优化的。

至于为什么不是赋值而是拷贝构造,是因为一个存在的对象给一个将要创建的对象,是拷贝构造,而一个存在的对象给一个也已经存在的对象才是赋值。



void func(Date aa)
{
	
}

int main()
{

	Date a;
	func(a);

	return 0;
}


void func(Date aa)
{
	
}

int main()
{

	//2构造匿名对象,匿名对象拷贝构造aa
	func(Date(2));

	return 0;
}

一行上,构造+拷贝构造优化为--->构造


void func(Date aa)
{
	
}

int main()
{

	//隐式类型转换,3构造临时对象,临时对象拷贝构造aa
	func(3);

	return 0;
}

同样被优化为只有构造。



测试用例二:

Date func()
{
	Date aa;
	return aa;
}

int main()
{

	Date a;
	a = func();

	return 0;
}

a构造,aa构造,接着返回值拷贝构造临时对象,aa析构,临时对象赋值给a,如果不优化,应该是这样:

  1. 构造-1
  2. 构造-2
  3. 拷贝构造-3
  4. 析构-2
  5. 赋值
  6. 析构-3
  7. 析构-1

Date func()
{
	Date aa;
	return aa;
}

int main()
{

	Date a = func();

	return 0;
}

这个优化更厉害了,构造,拷贝构造+拷贝构造,最后优化到只剩构造。

再次理解封装

我们用洗衣机来举例,就像我们知道洗衣机的一系列属性,将这些属性写到一个类里,这个类就是用来描述洗衣机属性的,但他是洗衣机吗?不是,用这些属性实例化出来的对象才是洗衣机,就像我们现实生活中尽管我们清楚洗衣机的属性,但是不买一个也没有办法去洗衣服。

练习题

求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)

class Sum
{
public:
    Sum()
    {
        _i++;
        _sum += _i;   
    }

    static int Get_sum()
    {
        return _sum;
    }

private:
    static int _i;
    static int _sum;

};

int Sum::_i = 0;
int Sum::_sum = 0;

class Solution 
{
public:
    int Sum_Solution(int n) 
    {
        Sum arr[n];
        return Sum::Get_sum();
    }
};

日期差值_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

class Sub
{
public:
    Sub(int date)
        :_date(date)
    {}

    int GetMonth(int year,int month) const;
    int operator-(Sub& d);

private:
    int _date;

    int _year;
    int _month;
    int _day;
};

int main()
{

    int Date1,Date2;
    cin >> Date1 >> Date2;

    int temp;
    if(Date1 > Date2)
    {
        temp = Date1;
        Date1 = Date2;
        Date2 = temp;
    }

    Sub d1(Date1);
    Sub d2(Date2);
    cout << (d1-d2) << endl;

    return 0; 
}
// 64 位输出请用 printf("%lld")

int Sub::operator-(Sub& d)
{
    
    _year = _date/10000;
    _month = _date/100%100;
    _day = _date%100;

    d._year = d._date/10000;
    d._month = d._date/100%100;
    d._day = d._date%100;

    int month = 1;
    int day = 1;
   
    int total = 0;
    if(_year == d._year)
    {
        if(_month == d._month)
        {
            return abs(_day-d._day+1);
        }
        else 
        {
            int month = 1;
            int total_1 = 0;
            while(month < _month)
            {
                total_1 += GetMonth(_year,month);
            }
            total_1 += _day;

            month = 1;
            int total_2 = 0;
            while(month < d._month) 
            {
                total_2 += GetMonth(_year,d._month);
            }
            total_2 += d._day;

            return abs(total_1 - total_2 + 1);
        }
    }
    else 
    {
        int month = 1;
        int total_1 = 0;

        while(month < _month)
        {
            total_1 += GetMonth(_year,month);
            month++;
        }

        total_1 += _day;
        total_1 = 365 - total_1;
    
        if(_month>2 && _year%4==0 && _year%100!=0 || _year%400==0)
        {
            total_1--;
        }

        month = 1;
        int total_2 = 0;
        while(month < d._month) 
        {
            total_2 += GetMonth(_year,month);
            month++;
        }
        
        total_2 += d._day;
        total = total_1 + total_2;

        if(d._year - _year > 1)
        {
            for(int i=_year+1; i<d._year; i++)
            {
                if(_year%4==0 && _year%100!=0 || _year%400==0)
                {
                    total++;
                }
            }

            total += 365 * (d._year-1);
        }
    }
    

    return total + 1;
 
}

int Sub::GetMonth(int year,int month) const
{
    int month_day[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 month_day[month];
}

打印日期_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

int main() 
{
    int year;
    int n;

    int month_day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    while(scanf("%d %d",&year,&n) != EOF)
    {
        int month = 1;
        int day = 1;


        while(n > month_day[month])
        {
            n -= month_day[month];
            month++;
        }

        if(month > 2 && (year%4 ==0 && year%100 != 0 || year%400 == 0))
        {
            n--;
            if(n == 0)
            {
                month--;
                n = 29;
            }
        }

        day = n;
        printf("%d-%02d-%02d\n",year,month,day);
    }

}
// 64 位输出请用 printf("%lld")

日期累加_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

int main() 
{
    int n;
    cin >> n;

    int year,month,day,Add_Day;
    int month_day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

    while(n--)
    {
        cin >> year >> month >> day >> Add_Day;

        int count = 0;
        while(count < Add_Day)
        {
            count++;

            day++;

            int num = month_day[month];
            if(month == 2 && (year%4 == 0 && year%100 != 0 || year % 400 == 0))
            {
                num++;
            }

            if(day > num)
            {
                day = 1;
                month++;
            }

            if(month == 13)
            {
                month = 1;
                year++;
            }
        }
        
        printf("%d-%02d-%02d\n",year,month,day);
    }


}
// 64 位输出请用 printf("%lld")

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

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

相关文章

瑞禧生物分享~普鲁士蓝纳米酶 Prussian Blue PB

名称&#xff1a;普鲁士蓝纳米酶&#xff1a;Fe4[Fe(CN)6]3、KFe[Fe(CN)6] NZs 包装&#xff1a;1mg/ml 应用领域&#xff1a;可作为抗氧化、抗炎新材料&#xff0c;同时具有载药、光热疗、炎症组织成像、构建生物传感器件等领域。 普鲁土蓝(Prusian Blue)&#xff0c;是一种…

gma 2 教程(三)坐标参考系统:3.投影方法

安装 gma&#xff1a;pip install gma 地图投影是利用一定数学法则把地球表面的经、纬线转换到平面上的理论和方法。由于地球是一个赤道略宽两极略扁的不规则的梨形球体&#xff0c;故其表面是一个不可展平的曲面&#xff0c;所以运用任何数学方法进行这种转换都会产生误差和变…

tbh常用的绘图快捷键

1、Altb -> 笔刷 2、Alt/ -> 画笔 3、按住Shift 绘出的线条是直线 4、按住shiftalt 绘出来的线条是水平线或垂直线 5、alte ->橡皮擦 6、alts ->选择工具 7、altq -> 轮廓编辑器 以下操作都是在选中轮廓编辑器下操作的&#xff1a; 按住alt…

高效管理:在文件夹名称左边添加关键字,实现批量重命名

在高效的文件管理中&#xff0c;对文件夹进行合理命名和重命名是十分关键的。有时候&#xff0c;我们可能需要在一批文件夹的名称左边添加特定的关键字&#xff0c;以便更好地组织和管理这些文件夹。为了实现这个目标&#xff0c;我们可以使用云炫文件管理器一些简单的步骤来实…

Java配置47-Spring Eureka 未授权访问漏洞修复

文章目录 1. 背景2. 方法2.1 Eureka Server 添加安全组件2.2 Eureka Server 添加参数2.3 重启 Eureka Server2.4 Eureka Server 升级版本2.5 Eureka Client 配置2.6 Eureka Server 添加代码2.7 其他问题 1. 背景 项目组使用的 Spring Boot 比较老&#xff0c;是 1.5.4.RELEASE…

云栖侧记:3点感悟…

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 2023年10月30日-11月2日&#xff0c;4天时间&#xff0c;我有幸参加了阿里云一年一度最重要的云栖大会&#xff0c;不过今天才写了个侧记文章&#xff0c;因为都拍视频去了&#xff0c;先说说参会感…

推广产品难?媒介盒子分享如何在软文中植入产品信息

产品想要卖得好&#xff0c;商家除了保证产品质量外&#xff0c;还需要善用推广&#xff0c;将产品打出知名度&#xff0c;软文推广就是很不错的方式&#xff0c;但是企业在推广时经常无法做到自然融入产品信息&#xff0c;导致推广没啥效果&#xff0c;今天媒介盒子就来告诉大…

uniapp小程序九宫格抽奖

定义好奖品下标&#xff0c;计时器开始抽奖&#xff0c;请求接口&#xff0c;出现中奖奖品之后&#xff0c;获取中奖商品对应的奖品下标&#xff0c;再次计时器判断当前移动的小标是否为中奖商品的下标&#xff0c;并且是否转到3圈&#xff08;防止转1圈就停止&#xff09;&…

3 数据库系统核心知识点

一、事务 先回顾一下事务的概念&#xff1a; 事务指的是满足 ACID 特性的一组操作&#xff0c;可以通过 Commit 提交一个事务&#xff0c;也可以使用 Rollback 进行回滚ACID 1. 原子性(Atomicity) 1.事务被视为不可分割的最小单元&#xff0c;事务的所有操作要么全部提交成…

【算法】背包问题——01背包

题目 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&#xff0…

算法通关村第六关|青铜|树通过序列构造二叉树

1.二叉树的性质 1.在二叉树的第 i 层上至多有 2^(i-1) 个结点。 2.深度为 k 的二叉树至多有 2^k - 1 个结点。 3.对于任意一棵二叉树&#xff0c;如果叶节点数为 N0 &#xff0c;度数为 2 的结点总数为 N2 &#xff0c;则 N0N21 。 4.具有 n 个结点的完全二叉树的深度为 lo…

uniapp原生插件之安卓华为统一扫码HMS Scan Kit

插件介绍 华为统一扫码服务&#xff08;Scan Kit&#xff09;提供便捷的条形码和二维码扫描、解析、生成能力 插件地址 安卓华为统一扫码HMS Scan Kit - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 详细使用文档 详细使用文档 插件申请权限 android.permi…

Uniapp中使用Echarts

在小程序中使用echarts 我直接调用了HbuilderX的百度图表进行使用 LimeUi - 多端uniapp组件库 (qcoon.cn) 通用代码去官网找一下就好了赋值进去第一个柱状图表就可以显示了 地图的使用 <template><view style"height: 750rpx"><l-echart ref"…

软件测试用例方法---边界值法

原则&#xff1a; 输入最小值&#xff08;min&#xff09;、稍大于最小值&#xff08;min&#xff09;、域内任意值&#xff08;nom&#xff09;、稍小于最大值&#xff08;max-&#xff09;、最大值&#xff08;max&#xff09; 写法&#xff1a;“单故障”假设&#xff08;致…

java后端响应结果Result

目录 一、Result1-1、响应代码1-2、调用响应1-3、在前端vue页面使用方法 一、Result 1-1、响应代码 package com.aaa.common;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data AllArgsConstructor NoArgsConstructor public cla…

Breakpad在Windows,Linux双平台编译、集成以及dump文件的分析

Breakpad在Windows&#xff0c;Linux双平台编译、集成以及dump文件的分析 1、Windows平台 Windows平台上非常好的参考文档&#xff1a; https://r12f.com/posts/google-breakpad-1-introduction-with-windows/ https://r12f.com/posts/google-breakpad-2-implementations-o…

数字银行:数据安全的挑战与对策

随着科技的进步和互联网的普及&#xff0c;传统的银行业务逐渐向数字化转型。数字银行&#xff0c;以其高效、便捷、个性化的服务特点&#xff0c;正在改变着人们的生活方式。然而&#xff0c;与此同时&#xff0c;数据安全问题也日益凸显。如何在享受数字银行便利的同时&#…

项目实战:添加新库存记录

1、在index.html添加超链接&#xff0c;添加新库存add.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"style/index.css"…

项目实战:修改水果库存系统特定库存记录

1、在edit.html修改库存页面添加点击事件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"style/index.css"><script s…

kubernetes集群编排——k8s存储

configmap 字面值创建 kubectl create configmap my-config --from-literalkey1config1 --from-literalkey2config2kubectl get cmkubectl describe cm my-config 通过文件创建 kubectl create configmap my-config-2 --from-file/etc/resolv.confkubectl describe cm my-confi…