《C++PrimerPlus》第13章 类继承

13.1 一个简单的基类

基类和派生类示例(球会会员管理)

头文件tabtenn1.h

#ifndef __TABTENN1_H__
#define __TABTENN1_H__

#include <iostream>
#include <string>

using namespace std;

class TableTennisPlayer
{
	private:
		string firstname; 
		string lastname;
		bool hasTable; // 是否有球桌
	public:
		TableTennisPlayer(const string &fn = "none", const string &ln = "none", bool ht = false);
		void Name() const;
		bool HasTable() const{return hasTable;}
		void ResetTable(bool v){hasTable = v;}
};

class RatedPlayer : public TableTennisPlayer // 派生类
{
private:
	unsigned int rating; // 比分
public:
	RatedPlayer(unsigned int r = 0, const string &fn = "none", const string &ln = "none", bool ht = false); // 构造函数
	RatedPlayer(unsigned int r, const TableTennisPlayer &tp); // 构造函数
	unsigned int Rating() const { return rating; } // 显示比分
	void ResetRating(unsigned int r) { rating = r; } // 复位比分
};

#endif

源代码main.cpp

#include <iostream>
#include "tabtenn1.h"

using namespace std;

int main(void)
{
	RatedPlayer rplay1(1140, "Mallory", "Duck", false);
	rplay1.Name(); // 派生类使用基类的成员函数
	if (rplay1.HasTable())
		cout << ": has a table." << endl;
	else
		cout << ": hasn't a table." << endl;

	rplay1.Name();
	cout << ": Rating: " << rplay1.Rating() << endl;

	TableTennisPlayer player1("Tara", "Boomdea", false);
	RatedPlayer rplayer2(1212, player1); // 调用第二个构造函数
	cout << "Name: ";
	rplayer2.Name();
	cout << ": Rating : " << rplayer2.Rating() << endl;

	return 0;
}

源代码tabtenn1.cpp

#include "tabtenn1.h"

TableTennisPlayer::TableTennisPlayer(const string &fn, const string &ln, bool ht)
{
	firstname = fn;
	lastname = ln;
	hasTable = ht;
}

void TableTennisPlayer::Name() const
{
	cout << lastname << ", " << firstname;
}

RatedPlayer::RatedPlayer(unsigned int r, const string &fn, const string &ln, bool ht) : TableTennisPlayer(fn, ln, ht) {
	rating = r;
}

RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer &tp) : TableTennisPlayer(tp) { // 调用基类的复制构造函数(隐式调用,编译器自动生成)
	rating = r;
}

13.2 继承:is-a关系

13.3 多态公有继承

多态公有继承示例(银行的两类账户)

头文件brass.h

#ifndef __BRASS_H__
#define __BRASS_H__

#include <iostream>
#include <string>
using namespace std;

class Brass {
private:
	string fullName; // 客户姓名
	long acctNum; // 账号
	double balance; // 当前结余
public:
	Brass(const string &s = "Null", long an = -1,
		double bal = 0.0); // 创建账户(构造函数)
	void Deposit(double amt); // 存款
	virtual void Withdraw(double amt); // 取款(虚)
	double Balance() const; // 显示当前余额
	virtual void ViewAcct() const; // 显示账户信息(虚)
	virtual ~Brass(){}
};

class BrassPlus : public Brass { // 派生类
private:
	double maxLoan; // 透支上限
	double rate; // 透支利率
	double owesBank; // 当前的透支总额
public:
	BrassPlus(const string &s = "Null", long an = -1, double bal = 0.0,
		double ml = 500.0, double rate = 0.11125); // 构造函数
	BrassPlus(const Brass &ba, double ml = 500.0, double rate = 0.11125); // 构造函数
	virtual void ViewAcct() const; // 显示账户信息(多态)(虚)
	virtual void Withdraw(double amt); // 取款(虚)
	void ResetMax(double m) { maxLoan = m; } // 修改存款最大值
	void ResetRate(double r) { rate = r; } // 修改利率
	void ResetOwes() { owesBank = 0.0; } // 将透支总额复位为0
};


#endif // !__BRASS_H__

源代码main.cpp

#include "brass.h"

const int CLIENTS = 3;

int main()
{
	Brass Rick("Rick", 123456, 4000.0);
	BrassPlus Jack("Jack", 654321, 3000.0);
	Rick.ViewAcct();
	cout << endl;
	Jack.ViewAcct();
	cout << endl;

	cout << "Depositing $1000 into the Jack Account." << endl;
	Jack.Deposit(1000);
	Jack.ViewAcct();
	cout << endl;

	cout << "Withdraw $4200 from the Rick Account." << endl;
	Rick.Withdraw(4200);
	Rick.ViewAcct();
	cout << endl;

	cout << "Withdraw $4200 from the Jack Account." << endl;
	Jack.Withdraw(4200);
	Jack.ViewAcct();
	cout << endl;

	/*******************使用引用或指针************************/
	// 使用基类指针:可以指向基类对象,也可以指向派生类对象
	Brass *p_clients[CLIENTS]; //基类的指针数组,每个元素都是一个基类的指针
	string temp;
	long tempnum;
	double tempbal;
	int kind;
	for (int i = 0; i < CLIENTS; i++) {
		cout << "Enter the client's name: ";
		getline(cin, temp);
		cout << "Enter client's account number: ";
		cin >> tempnum;
		cout << "Enter opening balance: $";
		cin >> tempbal;
		cout << "Enter 1 for Brass Account or 2 for BrassPlus Account: ";
		while (cin >> kind && (kind != 1 && kind != 2))
			cout << "Please enter either 1 or 2: ";
		if (kind == 1)
			p_clients[i] = new Brass(temp, tempnum, tempbal); // 对类使用new,将会调用相应的构造函数
		else {
			double tmax, trate;
			cout << "Enter the overdraft limit: $";
			cin >> tmax;
			cout << "Enter the rate: ";
			cin >> trate;
			p_clients[i] = new BrassPlus(temp, tempnum, tempbal, tmax, trate);
		}
		while (cin.get() != '\n'); // 消耗掉回车
	}
	cout << endl;

	for (int i = 0; i < CLIENTS; i++) {
		// 虚方法,根据指针引用的对象来确定用哪种方法
		p_clients[i]->ViewAcct(); // 注意通过指针调用,用的是->
		cout << endl;
	}

	for (int i = 0; i < CLIENTS; i++) {
		// 必须要有虚析构函数,根据指针引用的对象来确定用哪种析构函数
		delete p_clients[i]; // 有new就有delete!
	}

	return 0;
}

源代码brass.cpp

#include "brass.h"

Brass::Brass(const string &s, long an, double bal) {
	fullName = s;
	acctNum = an;
	balance = bal;
}

void Brass::Deposit(double amt) {
	if (amt < 0)
		cout << "Negative value is not allowed!" << endl;
	else
		balance += amt;
}

void Brass::Withdraw(double amt) {
	if (amt < 0)
		cout << "Negative value is not allowed!" << endl;
	else if (amt <= balance)
		balance -= amt;
	else
		cout << "Withdraw amount exceeded your balance!" << endl;
}

double Brass::Balance() const {
	return balance;
}

void Brass::ViewAcct() const {
	cout << "Client: " << fullName << endl;
	cout << "Account number: " << acctNum << endl;
	cout << "Balance: $" << balance << endl;
}

BrassPlus::BrassPlus(const string &s, long an, double bal, double ml,
	double r) : Brass(s, an, bal) {
	maxLoan = ml;
	rate = r;
	owesBank = 0.0;
}

BrassPlus::BrassPlus(const Brass &ba, double ml, double r) : Brass(ba) {
	maxLoan = ml;
	rate = r;
	owesBank = 0.0;
}

void BrassPlus::ViewAcct() const { // 定义的时候不需要加virtual
	Brass::ViewAcct(); // 派生类调用基类方法
	cout << "Maxium load: $" << maxLoan << endl;
	cout << "Loan Rate: " << rate << endl;
	cout << "Owed to bank: $" << owesBank << endl;
}

void BrassPlus::Withdraw(double amt) {
	double bal = Balance();
	if (amt <= bal) // 取的钱小于余额
		Brass::Withdraw(amt);
	else if (amt <= bal + maxLoan - owesBank) { // 透支取钱
		double advance = amt - bal; // 透支的钱
		owesBank = advance * (1.0 + rate); // 欠银行的钱(加上利息)
		cout << "Bank Advance: $" << advance << endl;
		cout << "Finance charge: $" << advance * rate << endl;
		Deposit(advance); // 存钱
		Brass::Withdraw(amt); // 取钱
	}
	else // 透支也不够取
		cout << "Credit limit exceeded!" << endl;


}

13.4 静态联编和动态联编

13.5 访问控制:protected

13.6 抽象基类

抽象类示例(银行的两类账户)

头文件acctabc.h

#ifndef __ACCTABC_H__
#define __ACCTABC_H__

#include <iostream>
#include <string>
using namespace std;

class AcctABC {
private:
	string fullName;
	long acctNum;
	double balance;
protected:
	const string &FullName() const { return fullName; } // 返回客户姓名
	long AcctNum() const { return acctNum; } // 返回客户账号
public:
	AcctABC(const string &s = "Null", long an = -1,
		double bal = 0.0); // 构造函数
	void Deposit(double amt); // 存款
	virtual void Withdraw(double amt) = 0; // 取款(纯虚函数)
	double Balance() const { return balance; } // 显示当前余额
	virtual void ViewAcct() const = 0; // 显示账户信息(纯虚函数)
	virtual ~AcctABC(){} // 析构函数(虚函数)
};

class Brass : public AcctABC{
public:
	Brass(const string &s = "Null", long an = -1,
		double bal = 0.0) : AcctABC(s, an, bal) {} // 创建账户(构造函数)
	virtual void Withdraw(double amt); // 取款(虚)
	virtual void ViewAcct() const; // 显示账户信息(虚)
	virtual ~Brass(){}
};

class BrassPlus : public AcctABC{ // 派生类
private:
	double maxLoan; // 透支上限
	double rate; // 透支利率
	double owesBank; // 当前的透支总额
public:
	BrassPlus(const string &s = "Null", long an = -1, double bal = 0.0,
		double ml = 500.0, double rate = 0.11125); // 构造函数
	BrassPlus(const Brass &ba, double ml = 500.0, double rate = 0.11125); // 构造函数
	virtual void ViewAcct() const; // 显示账户信息(多态)(虚)
	virtual void Withdraw(double amt); // 取款(虚)
	void ResetMax(double m) { maxLoan = m; } // 修改存款最大值
	void ResetRate(double r) { rate = r; } // 修改利率
	void ResetOwes() { owesBank = 0.0; } // 将透支总额复位为0
};

#endif // !__BRASS_H__

源代码main.cpp

#include "acctabc.h"

const int CLIENTS = 3;

int main()
{
	AcctABC *p_clients[CLIENTS]; //基类的指针数组,每个元素都是一个基类的指针
	string temp;
	long tempnum;
	double tempbal;
	int kind;
	for (int i = 0; i < CLIENTS; i++) {
		cout << "Enter the client's name: ";
		getline(cin, temp);
		cout << "Enter client's account number: ";
		cin >> tempnum;
		cout << "Enter opening balance: $";
		cin >> tempbal;
		cout << "Enter 1 for Brass Account or 2 for BrassPlus Account: ";
		while (cin >> kind && (kind != 1 && kind != 2))
			cout << "Please enter either 1 or 2: ";
		if (kind == 1)
			p_clients[i] = new Brass(temp, tempnum, tempbal); // 对类使用new,将会调用相应的构造函数
		else {
			double tmax, trate;
			cout << "Enter the overdraft limit: $";
			cin >> tmax;
			cout << "Enter the rate: ";
			cin >> trate;
			p_clients[i] = new BrassPlus(temp, tempnum, tempbal, tmax, trate);
		}
		while (cin.get() != '\n'); // 消耗掉回车
	}
	cout << endl;

	for (int i = 0; i < CLIENTS; i++) {
		// 虚方法,根据指针引用的对象来确定用哪种方法
		p_clients[i]->ViewAcct(); // 注意通过指针调用,用的是->
		cout << endl;
	}

	for (int i = 0; i < CLIENTS; i++) {
		// 必须要有虚析构函数,根据指针引用的对象来确定用哪种析构函数
		delete p_clients[i]; // 有new就有delete!
	}

	return 0;
}

源代码acctabc.cpp

#include "acctABC.h"

AcctABC::AcctABC(const string &s, long an, double bal) {
	fullName = s;
	acctNum = an;
	balance = bal;
}

void AcctABC::Deposit(double amt) {
	if (amt < 0)
		cout << "Negative value is not allowed!" << endl;
	else
		balance += amt;
}

void AcctABC::Withdraw(double amt) {
	balance -= amt;
}

void Brass::Withdraw(double amt) {
	if (amt < 0)
		cout << "Negative value is not allowed!" << endl;
	else if (amt <= Balance())
		AcctABC::Withdraw(amt);
	else
		cout << "Withdraw amount exceeded your balance!" << endl;
}

void Brass::ViewAcct() const {
	cout << "Client: " << FullName() << endl;
	cout << "Account number: " << AcctNum() << endl;
	cout << "Balance: $" << Balance() << endl;
}

BrassPlus::BrassPlus(const string &s, long an, double bal, double ml,
	double r) : AcctABC(s, an, bal) {
	maxLoan = ml;
	rate = r;
	owesBank = 0.0;
}

BrassPlus::BrassPlus(const Brass &ba, double ml, double r) : AcctABC(ba) {
	maxLoan = ml;
	rate = r;
	owesBank = 0.0;
}

void BrassPlus::ViewAcct() const { // 定义的时候不需要加virtual
	cout << "Client: " << FullName() << endl;
	cout << "Account number: " << AcctNum() << endl;
	cout << "Balance: $" << Balance() << endl;
	cout << "Maxium load: $" << maxLoan << endl;
	cout << "Loan Rate: " << rate << endl;
	cout << "Owed to bank: $" << owesBank << endl;
}

void BrassPlus::Withdraw(double amt) {
	double bal = Balance();
	if (amt <= bal) // 取的钱小于余额
		AcctABC::Withdraw(amt);
	else if (amt <= bal + maxLoan - owesBank) { // 透支取钱
		double advance = amt - bal; // 透支的钱
		owesBank = advance * (1.0 + rate); // 欠银行的钱(加上利息)
		cout << "Bank Advance: $" << advance << endl;
		cout << "Finance charge: $" << advance * rate << endl;
		Deposit(advance); // 存钱
		AcctABC::Withdraw(amt); // 取钱
	}
	else // 透支也不够取
		cout << "Credit limit exceeded!" << endl;


}

13.7 继承和动态内存分配

继承和动态内存分配示例(派生类使用或不使用new)

头文件dma.h

#ifndef __DMA_H___
#define __DMA_H___

#include <iostream>
using namespace std;

class baseDMA {
private:
	char *label;
	int rating;
public:
	baseDMA(const char *l = "null", int r = 0); // 构造函数
	baseDMA(const baseDMA &rs); // 复制构造函数
	virtual ~baseDMA(); // 析构函数(虚)
	baseDMA &operator=(const baseDMA &s); // 重载=运算符
	friend ostream &operator<<(ostream &os, const baseDMA &rs); // 重载<<运算符
};

class lacksDMA : public baseDMA {
private:
	enum { COL_LEN = 40 };
	char color[COL_LEN];
public:
	lacksDMA(const char *l = "null", int r = 0, const char *c = "blank"); // 构造函数
	lacksDMA(const baseDMA &rs, const char *c = "blank");
	friend ostream &operator<<(ostream &os, const lacksDMA &rs);
};

class hasDMA : public baseDMA {
private:
	char *style;
public:
	hasDMA(const char *l = "null", int r = 0, const char *s = "none");
	hasDMA(const baseDMA &rs, const char *s);
	hasDMA(const hasDMA &hs); // 复制构造函数
	~hasDMA(); // 析构函数
	hasDMA &operator=(const hasDMA &hs); // 重载=运算符
	friend ostream &operator<<(ostream &os, const hasDMA &rs); // 重载<<运算符
};

#endif

源代码main.cpp

#include "dma.h"

int main()
{
	baseDMA shirt("Protabelly", 8);
	cout << "Displaying baseDMA object: " << endl;
	cout << shirt;
	cout << "-----------------------------------" << endl;

	lacksDMA ballon("Blimpo", 4, "red");
	cout << "Displaying lacksDMA object: " << endl;
	cout << ballon;
	cout << "-----------------------------------" << endl;

	lacksDMA ballon2(ballon); // 调用默认复制构造函数
	cout << ballon2;
	cout << "-----------------------------------" << endl;

	hasDMA map("Keys", 5, "Mercator");
	cout << "Displaying hasDMA object: " << endl;
	cout << map << endl;
	cout << "-----------------------------------" << endl;

	hasDMA map2 = map; // 使用复制构造函数
	cout << map2 << endl;
	cout << "-----------------------------------" << endl;

	hasDMA map3; 
	map3 = map; // 使用重载赋值运算符
	cout << map3 << endl;

	return 0;
}

源代码dma.cpp

#include "dma.h"
#include <cstring>

baseDMA::baseDMA(const char *l, int r) {
	label = new char[strlen(l) + 1];
	strcpy_s(label, strlen(l) + 1, l);
	rating = r;
}

baseDMA::baseDMA(const baseDMA &rs) {
	label = new char[strlen(rs.label) + 1];
	strcpy_s(label, strlen(rs.label) + 1, rs.label);
	rating = rs.rating;
}

baseDMA::~baseDMA() {
	delete[] label;
}

baseDMA &baseDMA::operator=(const baseDMA &rs) {
	if (this == &rs) return *this;
	delete[] label;
	label = new char[strlen(rs.label) + 1];
	strcpy_s(label, strlen(rs.label) + 1, rs.label);
	rating = rs.rating;
	return *this;
}

ostream &operator<<(ostream &os, const baseDMA &rs) {
	os << "Label: " << rs.label << endl;
	os << "Rating: " << rs.rating << endl;
	return os;
}

lacksDMA::lacksDMA(const char *l, int r, const char *c) : baseDMA(l, r) {
	strncpy_s(color, COL_LEN, c, strlen(c)); // 注意strncpy和strncpy_s的区别
}

lacksDMA::lacksDMA(const baseDMA &rs, const char *c) : baseDMA(rs) {
	strncpy_s(color, COL_LEN, c, strlen(c));
}

ostream &operator<<(ostream &os, const lacksDMA &ls) {
	os << (const baseDMA &)ls; // 强制类型转换,使用基类的运算符输出基类的信息
	os << "Color: " << ls.color << endl;
	return os;
}

hasDMA::hasDMA(const char *l, int r, const char *s) : baseDMA(l, r) {
	style = new char[strlen(s) + 1];
	strcpy_s(style, strlen(s) + 1, s);
}

hasDMA::hasDMA(const baseDMA &rs, const char *s) : baseDMA(rs) {
	style = new char[strlen(s) + 1];
	strcpy_s(style, strlen(s) + 1, s);
}

hasDMA::hasDMA(const hasDMA &hs) : baseDMA(hs) {
	cout << "Copy construct function." << endl; // 标记一下复制构造函数被使用
	style = new char[strlen(hs.style) + 1];
	strcpy_s(style, strlen(hs.style) + 1, hs.style);
}

hasDMA::~hasDMA() {
	delete[] style;
}

hasDMA &hasDMA::operator=(const hasDMA &hs) {
	cout << "operator function." << endl; // 标记重载赋值运算符被使用
	if (this == &hs) return *this;
	// 基类的重载运算符的函数表示法,传递给this指针
	// 这里不能写出this,否则会无限递归
	baseDMA::operator=(hs);
	delete[] style;
	style = new char[strlen(hs.style) + 1];
	strcpy_s(style, strlen(hs.style) + 1, hs.style);
	return *this;
}

ostream &operator<<(ostream &os, const hasDMA &hs) {
	os << (const baseDMA &)hs; // 强制类型转换,使用基类的运算符输出基类的信息
	os << "Style: " << hs.style << endl;
	return os;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js实时监听input输入框值的变化

实习日记之通过调用common chemistry的api接口实现输入keyword查找cas号和mw。做了一个简单的html网页&#xff0c;用到了ajax技术。比较简单&#xff0c;适合刚入门的宝学习参考。代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&l…

理解 AQS 和 ReentrantLock

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、公平锁和非公平锁 1.1 含义 1.2 如何自我实现 1.2.1 公平锁实现&#xff1a; 1.2.2 非公平锁实现: 1.2.3 公平和非公平的区…

Leetcode的AC指南 —— 哈希法/双指针:15. 三数之和

摘要&#xff1a; Leetcode的AC指南 —— 15. 三数之和。题目介绍&#xff1a;给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且…

数据结构学习 Leetcode72 编辑距离

关键词&#xff1a;动态规划 最长公共子序列 题目&#xff1a; 思路&#xff1a; 这题我虽然做出来了但是还是有点迷糊。首先&#xff0c;这道题一定是和最长公共子序列相似的。 所以往最长公共子序列方向思考&#xff0c;考虑的它的状态和转移方程以及边界。 状态和转移方…

Ajax学习

文章目录 AjaxAjax 是什么Ajax 经典应用场景Ajax 原理示意图ajax的异步请求的方法ajax的逻辑:应用实例-验证用户名是否存在思路框架图:需求分析: 到数据库去验证用户名是否可用思路框架图大功告成:使用JQuery-Ajax实现上面相同的需求:Ajax Ajax 是什么 AJAX 即"Async…

【HTML5】第1章 HTML5入门

学习目标 了解网页基本概念&#xff0c;能够说出网页的构成以及网页相关名词的含义 熟悉Web标准&#xff0c;能够归纳Web标准的构成。 了解浏览器&#xff0c;能够说出各主流浏览器的特点。 了解HTML5技术&#xff0c;能够知道HTML5发展历程、优势以及浏览器对HTML5的支持情…

【嵌入式开发学习必备专栏】

文章目录 嵌入式开发学习必备专栏1.1 ARM Coresight SoC-400/SoC-600 专栏导读目录1.1.1 Performance Profiling1.1.2 ARM Coresight Debug 工具系列1.1.2.1 ARM DS5 系列1.1.2.2 劳特巴赫 Trace32 系列1.1.2.3 JTAG OpenOCD 系列 1.2 ARM Cache 专栏1.3 ARM AMBA Bus 专栏1.3.…

java使用JSON工具解析字符串、数组详解

一&#xff1a;问题 1.最近自己在前后端数据交互时需要进行JSON格式字符串、数组数据进行转换&#xff0c;进行问题整理 2.遇到需要JSON字符串转换的朋友可以阅读 二&#xff1a;解析步骤 1.第一点首先确定需求&#xff0c;明确需要转的字符串是一个对象还是一个数组&#…

C练习——判断三角形并求面积

题目&#xff1a;从健盘任意输入三角形的三边长为a,b,c,编程判断a,b,c的值能否构成一个三角形&#xff0c;若能构成三角形&#xff0c;则计算并输出三角形的面积&#xff0c;否则提示不能构成三角形。 已知构成三角形的条件是&#xff1a;任意两边之和大于第三边。 解析&#…

jQuery-Validate验证插件的使用步骤【详解】

jQuery-Validate验证插件的使用步骤详解 1. 写在前面2. 效果展示3. Validate环境的搭建4. Validate基本方法的使用5. 实现错误消息的本地化6. 实现远程验证7. 自定义验证方法8. 验证表单完整版8.1 Html表单8.2 表单验证js逻辑8.3 表单验证css样式 1. 写在前面 我们知道&#x…

windows11经常断网WiFi

解决方法&#xff1a;从官方网站下载&#xff0c;更新WiFi驱动程序&#xff0c;

Linux:apache优化(2)—— 网页传输压缩

网页传输压缩 客户端在请求httpd服务器数据&#xff0c;httpd服务器在返回数据包给客户端时&#xff0c;先对返回的数据进行压缩&#xff0c;压缩之后再传输 作用&#xff1a;配置 Apache 的网页压缩功能&#xff0c;是使用 Gzip 压缩算法来对 Apache 服务器发布的网页内容进行…

AI又进化了,AI 写代码工具

今年 AI 的发展可谓一日千里&#xff0c;相信不少同学应该都用过 AI 来帮助自己提高开发效率吧&#xff1f; 比如让 AI 根据注释生成代码、解释整段代码、提供技术问题的答疑、修改 Bug、生成单元测试等等。 在 12 月 28 日刚刚结束的 WAVE SUMMIT 深度学习开发者大会上&…

STM32CubeMX教程8 TIM 通用定时器 - 输出比较

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.1、外设初始化函数调用流程 3.2.2、外设中断函数调用流程 3.2.3、添加其他必要代码 4、常用函数 5…

Mysql 容易忘的 sql 指令总结

目录 一、操作数据库的基本指令 二、查询语句的指令 1、基本查询语句 2、模糊查询 3、分支查询 4、 分组查询 5、分组查询 6、基本查询总结&#xff1a; 7、子查询 8、连接查询 三、MySQL中的常用函数 1、时间函数 2、字符串函数 3、聚合函数 4、运算函数 四、表…

Leetcode 63 不同路径 II

题意理解&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 要求&#xff1a;机器人只能…

Jmeter学习总结(4)——提取接口响应内容JSON Extractor

后置提取常见的方式&#xff1a;正则表达式和JSON Extractor。 而接口响应大多是JSON格式。 在JSON提取器之前&#xff0c;可以根据响应结果去编写所需要的JSON表达式&#xff0c;在结果树中选择JSON PATH TESTER。 {"server_time": 1232333333333,"data&quo…

基于ssm的4S店预约保养系统开发+vue论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

双语!性能优越|融合黏菌和差分变异的量子哈里斯鹰算法SDMQHHO

前面的文章里卡卡介绍了哈里斯鹰优化算法(Harris Hawks Optimization, HHO).HHO是 Heidari等[1]于2019年提出的一种新型元启发式算法&#xff0c;设计灵感来源于哈里斯鹰在捕食猎物过程中的合作行为以及突然袭击的狩猎风格&#xff0c;具有需调参数少、原理简单易实现、局部搜索…

Spring AOP<一>简介与基础使用

spring AOP 基础定义 含义使用切面组织多个Advice,Advice放在切面中定义。也就是说是定义通知的自定义类。自定义的AOP类Aspect连接点方法调用&#xff0c;异常抛出可以增强的点JoinPoint &#xff1a;也就是**被增强的方法的总称&#xff0c;可以获取具体方法的信息&#xff…