类和对象(中)(构造函数、析构函数和拷贝构造函数)

news2024/11/24 17:45:07

1.类的六个默认成员函数

任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。

//空类
class Date{};

默认成员函数:用户没有显示实现,编译器会自动生成的成员函数称为默认成员函数

2.构造函数

构造函数 是一个 特殊的成员函数,名字与类名相同 , 创建类类型对象时由编译器自动调用 ,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次
构造函数主要任务不是开空间创建对象,而是初始化对象。
其特征如下:
        ① 函数名与类名相同。
        ② 无返回值。//不需要写void
        ③ 对象实例化时编译器 自动调用 对应的构造函数。
        ④ 构造函数可以重载。
多个构造函数,有多种初始化方式,一般情况,建议每个类,都可以写一个全缺省的构造(好用)
class Date
 {
  public:
      //他们俩构成函数重载,但是无参调用时会存在歧义
      // 1.无参构造函数
      Date()
     {
        _year = 1;
		_month = 1;
		_day = 1;
     }
  
      // 2.带参构造函数
      // 一般情况,建议每个类,都可以写一个全缺省的构造(好用)
      Date(int year=1, int month=1, int day=1)
     {
          _year = year;
         _month = month;
          _day = day;
     }
      void Print()
	 {
		cout << _year << "-" << _month << "-" << _day << endl;
	 }
 private:
      int _year;
      int _month;
      int _day;
 };

int main()
{
	//Date d1();  //d1后面不能带括号否则定义对象无法跟函数声明区分开
//Date func();//这就是d1为什么不能带括号
	Date d1;
	d1.Print();
//类型 对象(2024,4,2)
	Date d2(2024, 4, 2);//这里调用构造函数是对象名加参数列表  
//这里可以和函数声明进行区分,如下一行的函数声明所示
 //Date func(int x, int y, int z);
	d2.Print();

	Date d3(2024);
	d3.Print();

	Date d4(2024, 4);
	d4.Print();

	return 0;
}

        ⑤如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦            用户显式定义编译器将不再生成。

#include<iostream>
using namespace std;
class Date
{
public:
	/*
	// 如果用户显式定义了构造函数,编译器将不再生成
	Date(int year, int month, int day)
	{
	_year = year;
	_month = month;
	_day = day;
	}
	*/

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

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

int main()
{
	// 将Date类中构造函数屏蔽后,代码可以通过编译,因为编译器生成了一个无参的默认构造函数
	// 将Date类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再生成
	// 无参构造函数,放开后报错:error C2512: “Date”: 没有合适的默认构造函数可用
	Date d1;//对象实例化的时候自动调用对应的构造函数
	return 0;
}

如果用户显示定义了构造函数,编译器将不会生成无参的默认构造函数,这时候如果定义一个无参的类如Date d1,会编译失败。

⑥C++ 把类型分成内置类型 ( 基本类型 ) 和自定义类型。内置类型就是语言提供的数据类型,如:int/char.../任意类型指针 ,自定义类型就是我们使用 class/struct/union 等自己定义的类型。
如果我们没写构造函数,编译器自动生成构造函数,对于编译器自动生成的构造函数
对于内置类型的成员变量,编译器没有规定要不要做处理!(有些编译器会处理成0,但是C++标准并没有规定)
对于自定义类型的成员变量,才会调用他的默认成员函数即无参构造,如果没有无参构造会报错。(不传参就可以调用的那个构造,全缺省构造)
#include<iostream>
using namespace std;
class Time
{
public:
	Time()
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

这里我们发现编译器自动生成的构造函数对于自定义类型调用了它的默认构造函数。

注意: C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即: 内置类型成员变量在
类中声明时可以给默认值
class Time
{
public:
 Time()
 {
     cout << "Time()" << endl;
     _hour = 0;
     _minute = 0;
    _second = 0;
 }
private:
     int _hour;
     int _minute;
     int _second;
};

class Date
{
private:
 // 基本类型(内置类型)
 int _year = 1970;
 int _month = 1;
 int _day = 1;
 // 自定义类型
 Time _t;
};
int main()
{
     Date d;
     return 0;
}

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。

总结:不传参数就可以调用的函数就是默认构造

Ⅰ一般情况构造函数都需要我们自己显式去实现

Ⅱ只有少数情况下可以让编译器自动生成构造函数类似MyQueue,成员全是自定义类型

3.析构函数

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由
编译器完成的。而 对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

析构函数是特殊的成员函数,其特征如下:

①析构函数名是在类名前加上字符 ~
②无参数无返回值类型。
③一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
函数不能重载
④对象生命周期结束时,C++ 编译系统系统自动调用析构函数

⑤对于编译器自动生成的默认析构函数,对于自定义类型成员会调用它的析构函数。

跟构造函数类似:

a、内置类型不做处理       

b、自定义类型去调用他的析构

class Time
{
public:
 ~Time()
 {
 cout << "~Time()" << endl;
 }
private:
 int _hour;
 int _minute;
 int _second;
};
class Date
{
private:
 // 基本类型(内置类型)
 int _year = 1970;
 int _month = 1;
 int _day = 1;
 // 自定义类型
 Time _t;
};
int main()
{
 Date d;
 return 0;
}//对象在这里被销毁后,这里会自动调用析构函数

程序运行结束后输出: ~Time() ,在main 方法中根本没有直接创建 Time 类的对象,为什么最后会调用 Time 类的析构函数?
因为: main 方法中创建了 Date 对象 d ,而 d 中包含 4 个成员变量,其中 _year, _month,
_day 三个是 内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;而_t Time 类对 象,所以在d销毁时,要将其内部包含的 Time 类的 _t 对象销毁,所以要调用 Time 类的析构函数。但是:main函数 中不能直接调用Time 类的析构函数,实际要释放的是 Date 类对象,所以编译器会调用 Date 类的析构函数,而Date 没有显式提供,则编译器会给 Date 类生成一个默认的析构函数,目的是在其内部调用Time 类的析构函数,即当Date 对象销毁时,要保证其内部每个自定义对象都可以正确销毁
 main函数中并没有直接调用 Time 类析构函数,而是显式调用编译器为 Date 类生成的默认析 构函数
注意:创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数
如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如
Date 类;有资源申请时,一定要写,否则会造成资源泄漏,比如 Stack
自动生成的构造函数和析构意义何在?两个栈实现一个队列
Stack.h如下:
#pragma once
#include<stdlib.h>
#include<iostream>
using namespace std;

class Stack
{
public:
	Stack(int n = 4);
	~Stack();

	//void Init();
	//void Destroy();

	void Push(int x);
	bool Empty();
	void Pop();
	int Top();
private:
	// 成员变量
	int* _a;
	int _top;
	int _capacity;
};

class Queue
{
public:
	void Init();
	void Push(int x);

};

Stack.cpp如下:

#include"Stack.h"

Stack::Stack(int n)//缺省参数声明和定义不能同时给,规定了只在声明时候给,定义的时候不给
{
	_a = (int*)malloc(sizeof(int)*n);
	_top = 0;
	_capacity = n;
}

Stack::~Stack()
{
	cout << "~Stack()" << endl;
	free(_a);
	_a = nullptr;
	_top = 0;
	_capacity = 0;
}

//void Stack::Init()//指明类的作用域就指明了类的出处
//{
//	_a = nullptr;
//	_top = 0;
//	_capacity = 0;
//}//任何一个变量都得先定义再使用,不符合语法报语法错误

//void Destroy()
//{
//	//...
//}

void Stack::Push(int x)
{
	// ...
	_a[_top++] = x;
}

bool Stack::Empty()
{
	return _top == 0;
}

void Stack::Pop()
{
	--_top;
}

int Stack::Top()
{
	return _a[_top - 1];
}

//void Queue::Push(int x)
//{
//
//}

test.cpp
#icnlude<Stack.h>
class MyQueue
{
private:
	Stack _pushst;
	Stack _popst;
};

int main()
{
	MyQueue q;
	return 0;
}

这里创建MyQuque类q时,会自动调用调用Stack类的默认构造函数,q销毁时,也会自动调用Stack类的默认析构函数。

下面是一个括号匹配问题,利用c和c++实现的比较,可以发现,利用c++的构造和析构特性后,会方便很多

实践中总结:
1、有资源需要显示清理,就需要写析构。如:Stack List
2、有两种场景不需要显示写析构,默认生成就可以了
a、没有资源需要清理,如:Date
b、内置类型成员没有资源需要清理。剩下的都是自定义类型成员
4.拷贝构造函数
拷贝构造函数: 只有单个形参 ,该形参是对本 类类型对象的引用 ( 一般常用 const 修饰 ) ,在用 已存 在的类类型对象创建新对象时由编译器自动调用
特征:
①拷贝构造函数 是构造函数的一个重载形式
拷贝构造函数的 参数只有一个 必须是类类型对象的引用 ,使用 传值方式编译器直接报错 因为会引发无穷递归调用。
class Date
{
public:
	Date(int year = 1970, int month =1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(Date d)错误写法
    //Date d2(d1);//d1传给了d,d2就是this
	Date(const Date& d)//加了const之后d的内容就无法修改
	{
		cout << "const Date& d" << endl;
        //this->_year = d._year;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
//	Date(Date* d)//规定这里不是拷贝构造,就是一个普通构造,编译器会自动生成一个默认的拷贝构造
//	{
//		_year = d->_year;
//		_month = d->_month;
//		_day = d->_day;
//	}

	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	// 基本类型(内置类型)
	int _year ;
	int _month ;
	int _day ;

};
void func(Date d)
{
	d.Print();
}
int main()
{
	Date d1(2024,4,18);
	Date d2(d1);
	func(d2);
	return 0;
}

//Date(Date d)是错误写法,

原因:对于自定义类型传值传参要调用拷贝构造完成,这是一种规定,自定义类型的拷贝都要调用拷贝构造才能完成。这里用d1去构建d2,规定需要调用拷贝构造,调用拷贝构造得先传参,先传参形成了一个新的拷贝构造,新的拷贝构造假设去调用,去调用这个拷贝构造,又要先传参,从逻辑上来说就是一个无穷递归

对于
func(d2);
void func(Date d)
{
	d.Print();
}
Date(const Date& d)
{
	cout << "const Date& d" << endl;
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

与构造和析构函数一样,内置类型就直接传,自定义类型传值传参就要调用拷贝构造完成,这里调用func之前先传参,传参就会形成一个拷贝构造,d是d2的别名,函数结束回来,传参完成,参数的传递就是完成拷贝构造调用,最后调用调用func函数,结束

也可以从建立函数栈帧的方式去看函数func(d2)的调用

当然也可以采用指针或者引用的方式,这种方式不会调用拷贝构造。

	func(d2);
void func(Date& d)
{
    d.Print();
}
//这种方式也不会调用拷贝构造,d是d2的别名

    func(&d2);
void func(Date* d)
{
	d->Print();
}
//这种情况下没有拷贝构造,因为传的是内置类型,把d2地址进行传递,用指针进行接收

③若未显示定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

class Time
{
public:
	Time()
	{
		_hour = 1;
		_minute = 1;
		_second = 1;
	}
	Time(const Time& t)
	{
		_hour = t._hour;
		_minute = t._minute;
		_second = t._second;
		cout << "Time::Time(const Time&)" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d1;

	// 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数
	// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数
	Date d2(d1);
	return 0;
}

注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。
④深拷贝
编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,这是浅拷贝或者值拷贝,对于日期类不需要自己显示实现,值拷贝就是将一块空间里面的值按照字节一个一个的拷贝过来,有点像memcpy拷贝—样,memcpy就是按字节拷贝
但是如果内部有指针或者一些值指向资源,需要显示写析构释放,通常就需要显示写构造完成深拷贝,如:Stack Queue List等
//这里如何去掉Stack的拷贝构造会发现下面的程序会崩溃掉,这里就需要深拷贝去解决。
typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	Stack(const Stack& st)
	{
		_array = (DataType*)malloc(st._capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		memcpy(_array, st._array, st._size*sizeof(DataType));
		_size = st._size;
		_capacity = st._capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	bool Empty()
	{
		return _size == 0;
	}

	DataType Top()
	{
		return _array[_size - 1];
	}

	void Pop()
	{
		--_size;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};
class MyQueue
{
private:
	Stack _st1;
	Stack _st2;
	int _size = 0;
};
int main()
{
	Stack st1(10);
	st1.Push(1);
	st1.Push(1);
	st1.Push(1);

	Stack st2 = st1;
	st2.Push(2);
	st2.Push(2);

	while (!st2.Empty())
	{
		cout << st2.Top() << " ";
		st2.Pop();
	}
	cout << endl;
    //输出1 1 1
	while (!st1.Empty())
	{
		cout << st1.Top() << " ";
		st1.Pop();
	}
	cout << endl;
    //输出2 2 1 1 1 
	MyQueue q1;
	MyQueue q2(q1);
 //这里自定义类型会去调用栈的拷贝构造(栈的拷贝构造是深拷贝),内置类型完成值拷贝
	return 0;
}

注意:这里_array按照字节拷贝,相当于然s2的_array指向的空间和s1的_array指向的空间一样,但是这样会导致两个问题:(只要指针指向资源的都会有问题)
1.s1 push后s2上也能看见,因为s1改变的是和s2同一块空间的值,同时s1的size会改变,但是s2的size不会改变
⒉析构的时候,s1会free一次,s2也会free—次,相当于对一块空间free两次,也即析构两次
这里可以用深拷贝来解决,深拷贝就是你的形状和你的空间是什么样子就去开和你—样的空间,放一样的值,复制和你一样的出来。
在类里面加上如下的拷贝构造即可
	Stack(const Stack& st)
	{
		_array = (DataType*)malloc(st._capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		memcpy(_array, st._array, st._size*sizeof(DataType));
		_size = st._size;
		_capacity = st._capacity;
	}

实践中总结:
1、如果没有管理资源,一般情况不需要写拷贝构造,默认生成的拷贝构造就可以。如:Date
2、如果都是自定义类型成员,内置类型成员没有指向资源,也类似默认生成的拷贝构造就可以。如:MyQueue3、一般情况下,不需要显示写析构函数,就不需要写拷贝构造
4、如果内部有指针或者一些值指向资源,需要显示写析构释放,通常就需要显示写构造完成深拷贝。如:Stack Queue List等

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

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

相关文章

网络分析工具

为了实现业务目标&#xff0c;每天都要在网络上执行大量操作&#xff0c;网络管理员很难了解网络中实际发生的情况、谁消耗的带宽最多&#xff0c;并分析是否正在发生任何可能导致带宽拥塞的活动。对于大型企业和分布式网络来说&#xff0c;这些挑战是多方面的&#xff0c;为了…

[Leetcode]用栈实现队列

用栈实现队列&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元…

【智能算法】鸡群优化算法(CSO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2014年&#xff0c;X Meng等人受到鸡群社会行为启发&#xff0c;提出了鸡群优化算法&#xff08;Chicken Swarm Optimization, CSO&#xff09;。 2.算法原理 2.1算法思想 CSO算法的思想是基于对…

(六)PostgreSQL的组织结构(3)-默认角色和schema

PostgreSQL的组织结构(3)-默认角色和schema 基础信息 OS版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a;16.2 pg软件目录&#xff1a;/home/pg16/soft pg数据目录&#xff1a;/home/pg16/data 端口&#xff1a;57771 默认角色 Post…

软考135-上午题-【软件工程】-软件配置管理

备注&#xff1a; 该部分考题内容在教材中找不到。直接背题目 一、配置数据库 配置数据库可以分为以下三类&#xff1a; (1) 开发库 专供开发人员使用&#xff0c;其中的信息可能做频繁修改&#xff0c;对其控制相当宽松 (2) 受控库 在生存期某一阶段工作结束时发布的阶段产…

手机拍摄视频怎么做二维码?现场录制视频一键生成二维码

随着手机摄像头的像素不断提升&#xff0c;现在经常会通过手机的拍摄视频&#xff0c;然后发送给其他人查看。当我们想要将一个视频分享给多人去查看时&#xff0c;如果一个个去发送会比较的浪费时间&#xff0c;而且对方还需要下载接受视频后才可以查看&#xff0c;时间成本高…

简化PLC图纸绘制流程:利用SOLIDWORKS Electrical提升效率与准确性

效率一向是工程师比较注重的问题&#xff0c;为了提高工作效率&#xff0c;工程师绞尽脑汁。而在SOLIDWORKS Electrical绘制plc原理图时能有效提高PLC图纸的出图效率&#xff0c;并且可以减少数据误差。 在SOLIDWORKS Electrical绘制PLC图纸时&#xff0c;可以先创建PLC输入/输…

域名被污染了只能换域名吗?

域名污染是指域名的解析结果受到恶意干扰或篡改&#xff0c;使得用户在访问相关网站时出现异常。很多域名遭遇过污染的情况&#xff0c;但是并不知道是域名污染&#xff0c;具体来说&#xff0c;域名污染可能表现为以下情况&#xff1a;用户无法通过输入正确的域名访问到目标网…

24华中杯数学建模C题详解速通

本文针对光纤传感领域的曲线重构问题,提出了一套完整的数学建模与求解方法。通过对三个具体问题的分析和求解,揭示了曲率测量、曲线重构、误差分析等环节的内在联系和数学原理。本文综合运用了光纤传感、数值分析、微分几何等学科的知识,构建了波长-曲率转换模型、曲率连续化模…

Oracle——领先的企业级数据库解决方案

一、WHAT IS ORACLWE&#xff1a; ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一&#xff0c;ORACLE 通常应用于大型系统的数…

护眼台灯哪个牌子好?五大护眼效果好的护眼台灯强力推荐

护眼台灯哪个牌子好&#xff1f;护眼台灯比较好的牌子有书客、雷士、爱德华医生等&#xff0c;这些护眼台灯由于研发实力比较强&#xff0c;除了基本的照明功能&#xff0c;在护眼效果方面的表现也是比较不错的&#xff0c;这样的护眼台灯能够真正地起到对眼睛的保护作用&#…

读《AI营销画布》步骤五 保收获(十)

前言 正如书中所说&#xff0c;做到前四步就已经很了不起了&#xff0c;但是&#xff0c;现如今有很多公司的IT部门正从原来的公司分离&#xff0c;成立了不同的科技公司&#xff0c;以确保从费用成本中心变为利润中心&#xff0c;当然&#xff0c;分离出来不一定是AI促进的&am…

【问题处理】银河麒麟操作系统实例分享,adb读写缓慢问题分析

1.问题环境 处理器&#xff1a; HUAWEI Kunpeng 920 5251K 内存&#xff1a; 512 GiB 整机类型/架构&#xff1a; TaiShan 200K (Model 2280K) BIOS版本&#xff1a; Byosoft Corp. 1.81.K 内核版本 4.19.90-23.15.v2101.ky10.aarch64 第三方应用 数据库 2.问题…

OCP Java17 SE Developers 复习题14

答案 C. Since the question asks about putting data into a structured object, the best class would be one that deserializes the data. Therefore, ObjectInputStream is the best choice, which is option C. ObjectWriter, BufferedStream, and ObjectReader are no…

karpathy build make more --- 2

1 Introduction 用多层神经网络实现更复杂一点名字预测器。 2 方案 采用两层全连接层&#xff0c;中间采用tanh作为激活函数&#xff0c;最后一层用softmax&#xff0c;loss用cross-entropy. 2.1 实施 step1: 生成输入的字符,输入三个字符&#xff0c;输出一个字符. 采用了…

java的spring循环依赖、Bean作用域等深入理解

前言 通过之前的几篇文章将Spring基于XML配置的IOC原理分析完成&#xff0c;但其中还有一些比较重要的细节没有分析总结&#xff0c;比如循环依赖的解决、作用域的实现原理、BeanPostProcessor的执行时机以及SpringBoot零配置实现原理&#xff08;ComponentScan、Import、Impo…

推荐一款websocket接口测试工具

网址&#xff1a;Websocket在线测试-Websocket接口测试-Websocket模拟请求工具 http://www.jsons.cn/websocket/ 很简单输入以ws开后的网址就可以了 这个网址是你后台设置的 如果连接成功会砸提示框内显示相关字样&#xff0c;反之则不行

python爬虫之爬取携程景点评价(5)

一、景点部分评价爬取 【携程攻略】携程旅游攻略,自助游,自驾游,出游,自由行攻略指南 (ctrip.com) import requests from bs4 import BeautifulSoupif __name__ __main__:url https://m.ctrip.com/webapp/you/commentWeb/commentList?seo0&businessId22176&busines…

U.2 NVMe全闪存储阵列在高性能计算环境中的表现

用户利用高性能计算 (HPC) 先进的计算技术来执行大规模的复杂计算任务。这有助于短时间内解决复杂问题&#xff0c;与传统计算方法相比遥遥领先。Infortrend 存储解决方案专门针对密集型 HPC 工作负载进行了优化。新推出的U.2 NVMe全闪存储阵列GS 5024UE在0.3毫秒的延迟下提供1…

镭速助力企业集成OIDC实现安全高效的大文件数据传输

在当今数字化时代&#xff0c;企业尤其是科研机构、研究所和实验室等&#xff0c;对于大量敏感数据的传输安全和效率有着日益增长的需求。面对这一挑战&#xff0c;企业需要一种既能保障数据传输安全&#xff0c;又能提高传输效率的解决方案。镭速&#xff0c;作为一款面向企业…