c++|类和对象(下)

news2024/11/14 11:36:39

一、再谈构造函数

1.1初始化列表

在上一章节中,对于类我们可以形象的比喻为房子的图纸,而真正对于类的初始化可以比喻为建造了一个实体房子,即创建对象,对于房子中的各个房间都有特定的位置构造,那么对于类中的成员变量他们又是如何被初始化呢?如何去理解成员变量初始化?

在构造函数中,我们可以对成员变量赋初始值,那么这叫成员变量的初始化吗?其实并不是,这种情况称为函数体内的初始化,而且这种初始化可以多次赋值,在函数体内可以多次使用给不同值,而真正的成员变量初始化是在初始化列表中初始化的,且在初始化列表中只能被初始化一次。

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。 

例如:

#include <iostream>
using namespace std;


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

private:
	int _year;
	int _month;
	int _day;


};

int main()
{
	Date d1(2023, 12, 4);
	return 0;
}

1.2初始化列表的注意事项 

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

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

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

例如: 

#include <iostream>
using namespace std;


class A
{
public:
	A(int a)//有参构造函数
		:_a(a)
	{}
private:
	int _a;
};

class B
{
public:
	B(int a, int b)
		:_claim(a)//这三个都必须用初始化列表初始化
		, _copy(b)
		, _n(10)
	{}
private:
	A _claim;//自定义类型成员
	int& _copy;//引用成员变量
	const int _n;//const成员变量
};


int main()
{
    B b1(3,4);
	return 0;
}

对于引用成员变量和const成员变量在定义时都必须初始化,这是前面学过的内容,那么在类中,他们的初始化走的就是初始化列表。

自定义类型_claim成员中有一个有参构造函数 ,前面章节就学过在一个类中,会去调用该类中自定义类型成员的默认构造函数,而现在B类中因为有一个自定义有参构造函数,而A类中没有默认构造函数,只有一个有参构造函数,那么编译就会报错,说找不到默认构造函数,因此在这里需要使用初始化列表初始化自定义类型成员,B类的自定义构造函数才会去调用A类中的有参构造函数。

3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化 

#include <iostream>
using namespace std;

class Time
{
public:
	Time(int hour =0)
		:_hour(hour)
	{
		cout << "Time(int hour = 0)" << endl;
	}
private:
	int _hour;
};


class Date
{
public:
	Date(int day)
	{}
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};
int main()
{
	Date d1(1);
	return 0;
}

运行结果:

 上前面章节中,我们提到,对于内置类型成员和自定义类型成员都存在时,编译器会对他们都处理,而对于内置类型成员就会给初始值,只不过是随机值,在这里给的随机值其实走的就是初始化列表,由编译器自己实现。而对于自定义类型成员上面也已经说了必须走初始化列表。总结就是不管是内置还是自定义成员最好都使用初始化列表。

 4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关,意思就是成员变量的声明次序是什么样的,那么对应的在初始化列表中先走初始化的就是声明的顺序

#include <iostream>
using namespace std;


class A
{
public:
	A(int a)
		:_a1(a)
		,_a2(_a1)//先走这个,此时_a1是随机值,那么_a2就是随机值
	{}

	void print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};


int main()
{
	A aa(1);
	aa.print();
	return 0;
}

 运行结果:

_a2先声明,那么先走_a2的初始化,而此时_a1并没有被初始化,是随机值,那么_a2就是随机值,之后再走_a1的初始化,值为1 

注意:有些初始化列表或检查的工作,初始化列表也不能全部搞定,还要用函数体,例如:malloc了一个空间,那么空间检查工作就能用初始化列表搞定,而要用函数体。 

 1.3explict关键字

 对于只有一个参数和多个参数的构造函数,在创建对象并进行初始化时,可以通过隐式类型转换的方式来进行初始化,单参和多参的初始化是有区别的。而在构造函数前引入explicit关键字就可以禁止这种隐式类型转化。

先来看单参隐式类型转换:

class Date
{
public:
	Date(int year)//单参构造函数
		:_year(year)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2022);

	d1 = 2023;
	return 0;
}

上述代码中,除了定义对象时将值传过去初始化对像,还可以通过直接赋值初始化对象(d1 = 2023),他们之间类型不同,为什么可以直接赋值?

其实是发生了隐式类型转换,用2023构造了一个临时对象,再将该临时对象给了d1对象。

那么在构造函数前加上explicit就会禁止隐式类型转换。

class Date
{
public:
	explicit Date(int year)//单参构造函数
		:_year(year)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023);

	return 0;
}

 此时不能直接赋值,否则就会报错。

多参隐式类型转换:

class Date
{
public:
	Date(int year, int month=11, int day=8)//多参构造函数
		:_year(year)
		,_month(month)
		,_day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023);
	d1 = { 2023,12,8 };
	return 0;
}

与单参不一样的是多参构造进行初始化对象时,可以通过花括号来进行初始化,注意不要写成圆括号,这样就成了一个逗号表达式了。同理在构造函数前加上explicit就可以禁止该多参隐式类型转换。

注意:explicit修饰构造函数时,禁止的是传参时隐式类型的转换,但是有一种情况,在只有一个参数的情况下,如果进行强转的话,explicit就会失去效果。

class Date
{
public:
	explicit Date(int year)//单参构造函数
		:_year(year)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023);
	d1 = (Date)2023;
	return 0;
}

二、Static成员

2.1概念+特性

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

特性:

1.静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

2.静态成员变量必须在类外定义,定义时不添加static关键字,而声明则是在类里面

3.对于类中的静态成员,可以用 A::静态成员或者对象.静态成员来访问

4.静态成员函数没有隐藏的this指针,不能访问任何非静态成员

5.静态成员也是类的成员,受public、protected、private访问限定的限制

来看一个例子:实现一个类,计算程序中创建了多少个类对象。

#include <iostream>
using namespace std;

class A
{
public:
	A()
	{
		++_scount;
	}
	A(const A& t)
	{
		++_scount;
	}
	~A()
	{
		--_scount;
	}
	static int GetACount()//静态成员函数
	{
		return _scount;
	}
private:
	static int _scount;//静态成员变量,在类中是声明,受private保护
};

int A::_scount = 0;//静态成员变量在外面定义
int main()
{
	A a1, a2;
	A a3(a2);
	cout << A::GetACount() << endl;
    cout << a1.GetACount() << endl;
    cout << A().GetACount() << endl;//A()为匿名对象
	return 0;
}

运行结果:

其中用static定义的类成员存放在静态区,他就不属于具体的某个对象, 而是属于所有对象公有(a1,a2,a3),而平常定义的不是static的成员变量就是属于具体的某个对象,就不是公有的,所以对于_scount成员变量它是属于所有对象,_scount改变,那么每个对象中的_scount也会改变。通过类A创建了三个对象,那么_scount就加了三次,对于static定义的静态成员,不仅可以用A::静态成员形式来调用成员变量,还可以通过对象来调用,所以相比一些情况,当没有创建对象时,可以定义静态成员,并通过类直接调用静态成员。

还有一种情况就是创建匿名对象A(),那么又会调用一次构造函数,_scount再加1为4,匿名对象有一个特点就是他的生命周期只在他所在的一行。

想必有疑问的是静态成员不是共有的吗,为什么前面输出3而后面输出4,因为A()这个匿名对象是在后面定义的,前面的早已输出完了。还有就是析构函数不是会调用吗,那么_scount不是会自减吗,析构函数是在对象销毁前调用的,在输出完结果之后调用的。

 【问题】

1.静态成员函数可以调用非静态成员函数吗?

当然不可以,因为静态成员函数是没有this指针的,那么对象的地址就传不了给this指针。

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

当然可以,他有this指针,对象的地址可以传给this指针。

三、友元

 友元提供了一种突破封装的方式,有时提供了便利。正因如此,破坏了封装,增加了耦合度(彼此之间的联系程度),比如类与类之间通过友元就会增加联系,但可能会导致一个类被另一个类错用,所以友元不宜多用。

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

3.1友元函数 

先举个例子来引出友元函数:

尝试重载operator<<:

版本1(×)

#include <iostream>
using namespace std;

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

	ostream& operator << (ostream& _cout)
	{
		_cout << _year << "-" << _month << "-" << _day << endl;
		return cout;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 1, 6);
	cout << d1;
	return 0;
}

版本2(√) 

#include <iostream>
using namespace std;

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

	ostream& operator << (ostream& _cout)
	{
		_cout << _year << "-" << _month << "-" << _day << endl;
		return cout;
	}
//private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 1, 6);
	d1 << cout;
	return 0;
}

运行结果: 

 版本3(√)

#include <iostream>
using namespace std;

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

	
//private:
	int _year;
	int _month;
	int _day;
};

ostream& operator << (ostream& _cout,const Date& d1)
{
	_cout << d1._year << "-" << d1._month << "-" << d1._day << endl;
	return cout;
}

int main()
{
	Date d1(2024, 1, 6);
	cout << d1;
	return 0;
}

运行结果: 

 对于双操作数<<,第一个操作数为左操作数,第二个操作数为右操作数,版本1中cout为控制台对象作为第一个操作数,它的类型是ostream,与隐含的this指针抢占了第一个参数位置,this指针是指向当前对象,访问当前对象的成员函数和成员变量,所以this指针的类型是类的类型,与ostream类型不一致,所以cout对象不能传给this指针,且d1对象传给_cout也是类型不一致,若cout传给了_cout,那么d1对象传给谁呢?传给this指针吗?并不是,d1对象是第二个操作数,而this指针是接收第一个操作数,所以d1对象没有谁接收,虽然cout对象不会传给_cout对象。

版本2中,d1对象作为第一个操作数,传给隐含的this指针,cout对象传给_cout对象,这种方式在语法上是正确的,但是缺点就是可读性不好,正常认为是d1对象流入到cout控制台对象,而现在变成了cout控制台对象流入到d1对象。

版本3就解决了版本1,版本2的问题,将运算符的重载实现成了全局函数,而不是成员函数,全局函数中就不存在this指针了,就可以正常的指定参数。

在上面版本中,是将成员变量改成了公有的,才能对其访问,但正常来说成员变量是私有的,那么如何实现?这就引入了友元函数 :友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。look

#include <iostream>
using namespace std;

class Date
{
	friend ostream& operator << (ostream& _cout, const Date& d1);
	friend istream& operator >> (istream& _cin, Date& d1);
public:
	Date()
	{}
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}


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

ostream& operator << (ostream& _cout, const Date& d1)
{
	_cout << d1._year << "-" << d1._month << "-" << d1._day << endl;
	return cout;
}

istream& operator >> (istream& _cin,  Date& d1)
{
	_cin >> d1._year >> d1._month >> d1._day;
	return _cin;
}

int main()
{
	Date d1(2024, 1, 6);
	Date d2;
	cout << d1;
	cin >> d2;
	cout << d2;
	return 0;
}

已有两个全局的重载函数,这两个重载函数要想使用类中的私有成员,那么在类中,需声明该重载函数 并在前面加上friend,表明该重载函数是该类的朋友,有权限使用访问该类的私有成员。

注意:

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

 输出结果:

3.2友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。也就是我这个类是另一个类的朋友,那么我的类中的成员函数就可以访问另一个类中的私有成员。

注意:

  • 友元关系是单向的,不具有交换性。也就是我是他的朋友,我可以访问他的私有成员,但他不能访问我的成员。
  • 友元关系不能传递:如果c是b的友元,b是a的友元,则不能不能说明c是a的友元。
  • 友元关系不能继承,之后继承章节会讲。

例子: 

#include <iostream>
using namespace std;


class Time
{
	friend class Date;//Date类是Time类的友元,那么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 = 2024, int month =1, int day = 17)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	void friendsetTime(int hour = 20, int minute = 30, int second = 50)
	{
		//Date类中直接访问Time类中的私有成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;

	}

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


int main()
{
	Date d1;
	d1.friendsetTime();
	return 0;
}

友元不能传递的例子也是类比一下,小伙伴应该都没问题。

四、内部类

4.1概念+特性

 概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,他不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

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

特性:

1.内部类可以定义在外部类的public、protected、private都是可以的。

2.注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

3.sizeof(外部类)的大小不包括内部类的大小,与内部类没有任何关系

#include <iostream>
using namespace std;


class A
{
public:
	class B//B类为内部类,A类为外部类,B类天生就是A类的友元
	{
	public:
		void f(const A& a)
		{
			cout << k << endl;//内部类可以直接访问外部类的成员
			cout << a.k << endl;//通过外部类对象访问自己的成员变量
			cout << a.h << endl;
			cout << sizeof(A) << endl;//只计算了h的大小,内部类和静态成员变量都不算。
		}
	};
private:
	static int k;//静态成员内部声明
	int h;//这里没赋值,那么编译器会给个默认值
};

int A::k = 1;//静态成员外部定义

int main()
{
	A::B b;
	b.f(A());//A()为匿名对象
	return 0;
}

运行结果:

五、匿名对象

 在静态变量那提过了匿名对象,那么现在进一步进行描述以及注意的点。look

#include <iostream>
using namespace std;


class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << a << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};

class solution
{
public:
	int sum_solution(int n)
	{
		n += 10;
		return n;
	}
};

int main()
{
	A aa1=1;//隐式类型转换

	//A aa1();//不能这么定义对象,因为编译器无法识别这是对象定义,还是函数声明

	A();//这是匿名对象,匿名对象的特点是可以不用取名字,但是他的生命周期只有这一行
	
	A(2);//创建匿名对象并进行传参

	cout << solution().sum_solution(10) << endl;

	return 0;
}

运行结果:

匿名对象的生命周期只在定义的这一行,由代码也可以反映,匿名对象销毁了就调用了析构函数 ,匿名对象在很多地方下都挺方便的,减少了代码的冗余量。

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

在新的编译器下,对于自定义类型的对象进行拷贝时,进行以下组合,编译器会相应的优化:

  • 构造+拷贝构造->优化为构造
  • 拷贝构造+拷贝构造->拷贝构造
  • 拷贝构造+赋值重载->无法优化

接下来用一段代码进行解析 :

#include <iostream>
using namespace std;


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()
{

	
	f1(1);//隐式类型转换,1发生隐式类型转换,构造一个临时对象,再拷贝构造给aa对象。
	f1(A(2));//A(2)创建一个匿名对象,再拷贝构造给aa对象
	cout << endl;

	A aa2 = f2();//f2()函数中,return aa时创建了临时对象,aa由临时对象接收,临时对象再拷贝构造给f2(),f2()再拷贝给aa2对象
	cout << endl;

	A aa1;//创建一个对象
	aa1 = f2();//f2()中发生了拷贝构造,再将f2()赋值给aa1,注意此时进行的是赋值拷贝,而不是拷贝构造
	cout << endl;

	return 0;
}

 运行结果加分析:

由上面结果可以分析,在这些构造组合中,代码需在同一行才会发生优化。像aa1对象,是先创建了aa1对象,再进行赋值拷贝,这样就不会进行优化了 ,而是每一步都执行。还有一点,越新的编译器他的优化效果更厉害,上面结果及结论是在vs2019下适合,在vs2022并不一定。

创作不易,点个小赞吧~

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

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

相关文章

运维SRE-01 目录结构体系、find

1. Linux目录结构体系 Linux 核心目录的核心文件概述 1&#xff09; /etc下面 a) /etc/hosts 主机ip地址与域名(主机名)对应关系 b&#xff09; /etc/hostname 主机名 c) /etc/sysconfig/network-scripts/ifcfg-ens33或ifcfg-eth0 Linux网卡配置文件 d&#xff09;了解 /etc/i…

Prometheus的语句

1、node_cpu_seconds_total&#xff1a;监控项数据、指标项 2、node_cpu_seconds_total{cpu"0"}&#xff1a;时间序列 node_cpu_seconds_total 监控项数据&#xff08;指标项&#xff09; {cpu"0"} 标签 node_cpu_seconds_total{cpu"0"}&…

windows设置openDNS

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十九&#xff09;——windows设置openDNS 文章目录 win系统环境搭建&#xff08;十九&#xff09;——windows设置openDNS1.什么是openDNS&#xff1f;2.openDNS的ip是多少&#xff1f;3.设置DNS3.1 设置…

Android开发学习-中级控件

Drawable Android把所有能够显示的图形都抽象为Drawable类(可绘制的)。 这里的图形不止是图片&#xff0c;还包括色块、画板、背景等。 包含图片在内的图形文件放在res目录的各个drawable目录下&#xff0c;其中drawable目录一般保存描述性的XML文件&#xff0c;而图片文件一…

数据中心IP代理是什么?有何优缺点?海外代理IP全解

海外代理IP中&#xff0c;数据中心代理IP是很热门的选择。这些代理服务器为用户分配不属于 ISP&#xff08;互联网服务提供商&#xff09;且来自第三方云服务提供商的 IP 地址&#xff0c;是分配给位于数据中心的服务器的 IP 地址&#xff0c;通常由托管和云公司拥有。 这些 I…

搭建幻兽帕鲁需要什么样的服务器

作为一个开放世界生存制造类游戏《幻兽帕鲁》收获了空前绝后的热度&#xff0c;玩家们在游戏中通过在地图上捕捉收集到的“帕鲁”进行训练&#xff0c;合理利用他们的能力进行战斗&#xff0c;建立自己的家园、开辟新的世界、解锁新的冒险情节&#xff0c;获取更多游戏信息增加…

【JavaEE】UDP协议与TCP协议

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

LabVIEW传感器通用实验平台

LabVIEW传感器通用实验平台 介绍了基于LabVIEW的传感器实验平台的开发。该平台利用LabVIEW图形化编程语言和多参量数据采集卡&#xff0c;提供了一个交互性好、可扩充性强、使用灵活方便的传感器技术实验环境。 系统由硬件和软件两部分组成。硬件部分主要包括多通道数据采集卡…

华为云WAF,开启web网站的专属反爬虫防护罩

背景 从保护原创说起 作为一个原创技术文章分享博主&#xff0c;日常除了Codeing就是总结Codeing中的技术经验。 之前并没有对文章原创性的保护意识&#xff0c;直到在某个非入驻的平台看到了我的文章&#xff0c;才意识到&#xff0c;辛苦码字、为灵感反复试验创作出来的文…

Java学习笔记(十一)——常用类

一、包装类 &#xff08;一&#xff09;包装类和基本数据类型的转换 ​编辑 &#xff08;二&#xff09;包装类型和String类型的相互转换 &#xff08;三&#xff09;Integer类和Character类的常用方法 二、String &#xff08;一&#xff09;创建String对象的两种方式 …

Redis核心技术与实战【学习笔记】 - 11.响应延迟的波动问题及解决方案

在 Redis 的实际应用中&#xff0c;有一个非常严重的问题&#xff0c;就是 Redis 突然变慢了。举个例子&#xff0c;在秒杀场景下&#xff0c;一旦 Redis 变慢了&#xff0c;大量的用户下单请求就会被拖慢&#xff0c;也就是说&#xff0c;用户提交了下单申请&#xff0c;确没有…

【C语言】【力扣】1.两数之和

一、个人思考过程 int* twoSum(int* nums, int numsSize, int target, int* returnSize) {for(int i0;i<numsSize;i){for(int j0;j<numsSize;j){if((nums[i]nums[j]target)&&(i!j)){}}} 完成度&#xff1a;实现对nums[]数组的遍历和两数之和的判断。 问题&…

基于Java SSM框架实现药品销售系统项目【项目源码+论文说明】

基于java的SSM框架实现药品销售系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个药品销售系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述药品销…

介绍一款资料管理类浏览器

DT浏览器不同于普通意义上的浏览器&#xff0c;DT的含义就是数据资料的意思&#xff0c;更专注于资料的收集和管理&#xff0c;是一款资料管理类的浏览器&#xff0c;也是一款面向教育、培训、编程、技术和科研等资料收集领域的手机软件&#xff0c;主要有网络搜索、资料收藏&a…

Single-Head ViT;Faster Whisper;Transformer KF;Pick-and-Draw

本文首发于公众号&#xff1a;机器感知 Single-Head ViT&#xff1b;Faster Whisper&#xff1b;Transformer KF&#xff1b;Pick-and-Draw SHViT: Single-Head Vision Transformer with Memory Efficient Macro Design Recently, efficient Vision Transformers have shown …

Docker多节点部署Minio分布式文件系统并测试

文章目录 一、前提准备二、文件配置1. .env2. env/minio.env3. docker-compose-minio.yml 三、测试四、Java测试1. 引入依赖2. 增删改 一、前提准备 准备如下文件夹和文件 ./ ├── docker-compose-minio.yml ├── .env ├── env │ ├── minio.env ├── minio │…

windows安装oracle之后怎么连接使用

目录 1.打开SQl Developer 2.选择JDK 3.登录 4.创建表空间,用户 安装oracle的详细教程 WINDOWS安装Oracle11.2.0.4-CSDN博客 1.打开SQl Developer 找到 SQl Developer 2.选择JDK 根据你安装的oracle版本,因为我的oracle是安装的32位的,所以这里jdk也要选择32位 选择到ja…

熟悉MATLAB 环境

一、问题描述 熟悉MATLAB 环境。 二、实验目的 了解Matlab 的主要功能&#xff0c;熟悉Matlab 命令窗口及文件管理&#xff0c;Matlab 帮助系统。掌握命令行的输入及编辑&#xff0c;用户目录及搜索路径的配置。了解Matlab 数据的特点&#xff0c;熟悉Matlab 变量的命名规则&a…

【JAVA】Long类型返回到前端,精度丢失

一. 问题阐述 20位long类型的数字&#xff0c;从后端接口返回到前端后【四舍五入】 MYSQL端 &#xff08;1&#xff09;bigint (20) &#xff08;2&#xff09;具体某一条数据 JAVA端 &#xff08;1&#xff09;实体类 &#xff08;2&#xff09;服务类 &#xff08;3&…

DevExpress WinForms中文教程 - 如何创建可访问的WinForms应用?(一)

为用户创建易访问的Windows Forms应用程序不仅是最佳实践的体现&#xff0c;还是对包容性和以用户为中心的设计承诺。在应用程序开发生命周期的早期考虑与可访问性相关的需求可以节省长期运行的时间(因为它将决定设计决策和代码实现)。 一个可访问的WinForms应用程序提供了各种…