C++ 重载运算符 addition (+), subtraction (-) and multiplication (*)

C++ 重载运算符 addition +, subtraction - and multiplication *

  • 1. Operator Overloading (运算符重载)
  • 2. Developing an Operator Overloading Example
    • 2.1. Adding an Addition Operator (添加加法运算符)
    • 2.2. Overloading Restrictions (重载限制)
    • 2.3. 重载运算符 `-` 和 `*`
  • References

Two special member functions, the constructor and the destructor, that manage creating and discarding objects made to a class specification.
两个特殊的成员函数 (构造函数和析构函数),其作用是管理类对象的创建和删除。

As Bjarne Stroustrup, the creator of C++, suggested at a C++ conference for professional programmers:“Ease yourself into the language. Don’t feel you have to use all of the features, and don’t try to use them all on the first day.”
不要觉得必须使用所有的特性,不要在第一次学习时就试图使用所有的特性。

1. Operator Overloading (运算符重载)

Operator overloading is an example of C++ polymorphism. C++ enables you to define several functions that have the same name, provided that they have different signatures (argument lists).That is called function overloading, or functional polymorphism. Its purpose is to let you use the same function name for the same basic operation, even though you apply the operation to different data types. Operator overloading extends the overloading concept to operators, letting you assign multiple meanings to C++ operators.
运算符重载是一种形式的 C++ 多态。用户能够定义多个名称相同但特征标 (参数列表) 不同的函数的,这被称为函数重载或函数多态,旨在让您能够用同名的函数来完成相同的基本操作,即使这种操作被用于不同的数据类型。运算符重载将重载的概念扩展到运算符上,允许赋予 C++ 运算符多种含义。

C++ lets you extend operator overloading to user-defined types.
C++ 允许将运算符重载扩展到用户定义的类型,例如,允许使用 + 将两个对象相加。

To overload an operator, you use a special function form called an operator function.
要重载运算符,需使用被称为运算符函数的特殊函数形式。

An operator function has the following form, where OP is the symbol for the operator being overloaded:

operatorOP(argument-list)

For example, operator+() overloads the + operator and operator*() overloads the * operator. The OP has to be a valid C++ operator; you can’t just make up a new symbol. For example, you can’t have an operator@() function because C++ has no @ operator. But the operator[]() function would overload the [] operator because [] is the array-indexing operator. Suppose, for example, that you have a SalesPerson class for which you define an operator+() member function to overload the + operator so that it adds sales figures of one SalesPerson object to another. Then, if district2, yong, and qiang are all objects of the SalesPerson class, you can write this equation:
例如,operator+() 重载 + 运算符,operator*() 重载 * 运算符。OP 必须是有效的 C++ 运算符,不能虚构一个新的符号。例如,不能有 operator@() 这样的函数,因为 C++ 中没有 @ 运算符。然而,operator[]() 函数将重载 [] 运算符,因为 [] 是数组索引运算符。例如,假设有一个 SalesPerson 类,并为它定义了一个 operator+() 成员函数,以重载 + 运算符,以便能够将两个 SalesPerson 对象的销售额相加,则如果 district2, yong, and qiang 都是 SalesPerson 类对象,便可以编写这样的等式:

district2 = yong + qiang;

The compiler, recognizing the operands as belonging to the Salesperson class, replaces the operator with the corresponding operator function:

district2 = yong.operator+(qiang);

The function then uses the yong object implicitly (because it invoked the method) and the qiang object explicitly (because it’s passed as an argument) to calculate the sum, which it then returns. Of course, the nice part is that you can use the nifty + operator notation instead of the clunky function notation.
然后该函数将隐式地使用 yong (因为它调用了方法),而显式地使用 qiang 对象 (因为它被作为参数传递),来计算总和,并返回这个值。当然最重要的是,可以使用简便的 + 运算符表示法,而不必使用笨拙的函数表示法。

2. Developing an Operator Overloading Example

Now let’s generalize that to a Time class, using a method to handle addition. Let’s begin with an ordinary method, called Sum(), and then see how to convert it to an overloaded operator.
首先使用一个名为 Sum() 的常规方法,然后介绍如何将其转换为重载运算符。

  • time.h
// Time class before operator overloading
#ifndef TIME_H_
#define TIME_H_

class Time {
private:
	int hours;
	int minutes;

public:
	Time();
	Time(const int h, const int m = 0);
	~Time();

	void AddMinutes(const int m);
	void AddHours(const int h);
	void Reset(const int h = 0, const int m = 0);
	const Time Sum(const Time & time) const;
	void Show() const;
};

#endif

  • time.cpp
#include <iostream>

#include "time.h"

Time::Time() {
	std::cout << "Time::Time()" << std::endl;
	hours = minutes = 0;
}

Time::Time(const int h, const int m) {
	std::cout << "Time::Time(const int h, const int m): h=" << h << ", m=" << m << std::endl;
	hours = h;
	minutes = m;
}

Time::~Time() {
	std::cout << "Time::~Time(): hours=" << hours << ", minutes=" << minutes << std::endl;
}

void Time::AddMinutes(const int m) {
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::AddHours(const int h) {
	hours += h;
}

void Time::Reset(const int h, const int m) {
	hours = h;
	minutes = m;
}

const Time Time::Sum(const Time & time) const {
	std::cout << "Time::Sum(const Time & time)" << std::endl;
	Time sum;
	sum.minutes = minutes + time.minutes;
	sum.hours = hours + time.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

void Time::Show() const {
	std::cout << hours << " hours, " << minutes << " minutes";
}

  • sample.cpp
#include <iostream>

#include "time.h"

int main() {
	{
		Time planning;
		Time coding(2, 40);
		Time fixing(5, 55);
		Time total;

		std::cout << "planning time = ";
		planning.Show();
		std::cout << std::endl;

		std::cout << "coding time = ";
		coding.Show();
		std::cout << std::endl;

		std::cout << "fixing time = ";
		fixing.Show();
		std::cout << std::endl;

		total = coding.Sum(fixing);
		std::cout << "coding.Sum(fixing) = ";
		total.Show();
		std::cout << std::endl;
	}
	return 0;
}

在这里插入图片描述

Time::Time()
Time::Time(const int h, const int m): h=2, m=40
Time::Time(const int h, const int m): h=5, m=55
Time::Time()
planning time = 0 hours, 0 minutes
coding time = 2 hours, 40 minutes
fixing time = 5 hours, 55 minutes
Time::Sum(const Time & time)
Time::Time()
Time::~Time(): hours=8, minutes=35
Time::~Time(): hours=8, minutes=35
coding.Sum(fixing) = 8 hours, 35 minutes
Time::~Time(): hours=8, minutes=35
Time::~Time(): hours=5, minutes=55
Time::~Time(): hours=2, minutes=40
Time::~Time(): hours=0, minutes=0
请按任意键继续. . .

Note that the argument is a reference but that the return type is not a reference. The reason for making the argument a reference is efficiency. The code would produce the same results if the Time object were passed by value, but it’s usually faster and more memory-efficient to just pass a reference.
Sum() 函数的代码,参数是引用,但返回类型却不是引用。将参数声明为引用的目的是为了提高效率。如果按值传递 Time 对象,代码的功能相同,但传递引用,速度将更快,使用的内存将更少。

However, the return value can not be a reference. The reason is that the function creates a new Time object (sum) that represents the sum of the other two Time objects. Returning the object, as this code does, creates a copy of the object that the calling function can use. If the return type were Time &, however, the reference would be to the sum object. But the sum object is a local variable and is destroyed when the function terminates, so the reference would be a reference to a non-existent object. Using a Time return type, however, means the program constructs a copy of sum before destroying it, and the calling function gets the copy.
然而,返回值不能是引用。因为函数将创建一个新的 Time 对象 (sum),来表示另外两个 Time 对象的和。返回对象将创建对象的副本,而调用函数可以使用它。然而,如果返回类型为 Time &,则引用的将是 sum 对象。但由于 sum 对象是局部变量,在函数结束时将被删除,因此引用将指向一个不存在的对象。使用返回类型 Time 意味着程序将在删除 sum 之前构造它的拷贝,调用函数将得到该拷贝。

Don’t return a reference to a local variable or another temporary object. When the function terminates and the local variable or temporary object disappears, the reference becomes a reference to non-existent data.
不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。

2.1. Adding an Addition Operator (添加加法运算符)

You just change the name of Sum() to the odder-looking name operator+(). That’s right: You just append the operator symbol (+, in this case) to the end of operator and use the result as a method name. This is one place where you can use a character other than a letter, a digit, or an underscore in an identifier name.
Time 类转换为重载的加法运算符很容易,只要将 Sum() 的名称改为 operator+() 即可。只要把运算符放到 operator 的后面,并将结果用作方法名即可。在这里,可以在标识符中使用字母、数字或下划线之外的其他字符。

  • time.h
// Time class before operator overloading
#ifndef TIME_H_
#define TIME_H_

class Time {
private:
	int hours;
	int minutes;

public:
	Time();
	Time(const int h, const int m = 0);
	~Time();

	void AddMinutes(const int m);
	void AddHours(const int h);
	void Reset(const int h = 0, const int m = 0);
	Time operator+(const Time & time) const;
	void Show() const;
};

#endif

  • time.cpp
#include <iostream>

#include "time.h"

Time::Time() {
	std::cout << "Time::Time()" << std::endl;
	hours = minutes = 0;
}

Time::Time(const int h, const int m) {
	std::cout << "Time::Time(const int h, const int m): h=" << h << ", m=" << m << std::endl;
	hours = h;
	minutes = m;
}

Time::~Time() {
	std::cout << "Time::~Time(): hours=" << hours << ", minutes=" << minutes << std::endl;
}

void Time::AddMinutes(const int m) {
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::AddHours(const int h) {
	hours += h;
}

void Time::Reset(const int h, const int m) {
	hours = h;
	minutes = m;
}

Time Time::operator+(const Time & time) const {
	std::cout << "Time::operator+(const Time & time)" << std::endl;
	Time sum;
	sum.minutes = minutes + time.minutes;
	sum.hours = hours + time.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

void Time::Show() const {
	std::cout << hours << " hours, " << minutes << " minutes";
}

  • sample.cpp
#include <iostream>

#include "time.h"

int main() {
	{
		Time planning;
		Time coding(2, 40);
		Time fixing(5, 55);
		Time total;

		std::cout << "planning time = ";
		planning.Show();
		std::cout << std::endl;

		std::cout << "coding time = ";
		coding.Show();
		std::cout << std::endl;

		std::cout << "fixing time = ";
		fixing.Show();
		std::cout << std::endl;

		total = coding + fixing;
		// operator notation
		std::cout << "coding + fixing = ";
		total.Show();
		std::cout << std::endl;

		Time more_fixing(3, 28);
		std::cout << "more fixing time = ";
		more_fixing.Show();
		std::cout << std::endl;
		total = more_fixing.operator+(total);
		// function notation
		std::cout << "more_fixing.operator+(total) = ";
		total.Show();
		std::cout << std::endl;
	}

	return 0;
}

在这里插入图片描述

Time::Time()
Time::Time(const int h, const int m): h=2, m=40
Time::Time(const int h, const int m): h=5, m=55
Time::Time()
planning time = 0 hours, 0 minutes
coding time = 2 hours, 40 minutes
fixing time = 5 hours, 55 minutes
Time::operator+(const Time & time)
Time::Time()
Time::~Time(): hours=8, minutes=35
Time::~Time(): hours=8, minutes=35
coding + fixing = 8 hours, 35 minutes
Time::Time(const int h, const int m): h=3, m=28
more fixing time = 3 hours, 28 minutes
Time::operator+(const Time & time)
Time::Time()
Time::~Time(): hours=12, minutes=3
Time::~Time(): hours=12, minutes=3
more_fixing.operator+(total) = 12 hours, 3 minutes
Time::~Time(): hours=3, minutes=28
Time::~Time(): hours=12, minutes=3
Time::~Time(): hours=5, minutes=55
Time::~Time(): hours=2, minutes=40
Time::~Time(): hours=0, minutes=0
请按任意键继续. . .

Like Sum(), operator+() is invoked by a Time object, takes a second Time object as an argument, and returns a Time object. Thus, you can invoke the operator+() method by using the same syntax that Sum() uses.
Sum() 一样,operator+() 也是由 Time 对象调用的,它将第二个 Time 对象作为参数,并返回一个 Time 对象。因此,可以像调用 Sum() 那样来调用 operator+() 方法。

total = coding.operator+(fixing);  // function notation

但将该方法命令为 operator+() 后,也可以使用运算符表示法 (operator notation):

total = coding + fixing;  // operator notation

Either notation invokes the operator+() method. Note that with the operator notation, the object to the left of the operator is the invoking object, and the object to the right is the one passed as an argument.
这两种表示法都将调用 operator+() 方法。注意,在运算符表示法中,运算符左侧的对象是调用对象,运算符右边的对象是作为参数被传递的对象。

In short, the name of the operator+() function allows it to be invoked by using either function notation or operator notation. The compiler uses the operand types to figure out what to do.
operator+() 函数的名称使得可以使用函数表示法或运算符表示法来调用它,编译器将根据操作数的类型来确定如何做。

int a, b, c;
Time A, B, C;
c = a + b;  // use int addition
C = A + B;  // use addition as defined for Time objects
t4 = t1 + t2 + t3;  // valid?

Because addition is a left-to-right operator, the statement is first translated to this.
由于 + 是从左向右结合的运算符,因此上述语句首先被转换成下面这样:

t4 = t1.operator+(t2 + t3);

Then the function argument is itself translated to a function call, giving the following.
然后, 函数参数本身被转换成一个函数调用:

t4 = t1.operator+(t2.operator+(t3));

The function call t2.operator+(t3) returns a Time object that represents the sum of t2 and t3. This object then becomes the object of the t1.operator+() function call, and that call returns the sum of t1 and the Time object that represents the sum of t2 and t3. In short, the final return value is the sum of t1, t2, and t3, just as desired.
函数调用 t2.operator+(t3) 返回一个 Time 对象,表示 t2t3 的和。该对象成为函数调用 t1.operator+() 的参数,该调用返回 t1 与表示 t2t3 之和的 Time 对象的和。最后的返回值为 t1t2t3 之和,这正是我们期望的。

2.2. Overloading Restrictions (重载限制)

Overloaded operators don’t necessarily have to be member functions. However, at least one of the operands has to be a user-defined type.
重载的运算符不必是成员函数,但必须至少有一个操作数是用户定义的类型。

  • The overloaded operator must have at least one operand that is a user-defined type. This prevents you from overloading operators for the standard types. Thus, you can’t redefine the minus operator (-) so that it yields the sum of two double values instead of their difference. This restriction preserves program sanity, although it may hinder creative accounting.
    重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。因此,不能将减法运算符 - 重载为计算两个 double 值的和,而不是它们的差。虽然这种限制将对创造性有所影响,但可以确保程序正常运行。

  • You can’t use an operator in a manner that violates the syntax rules for the original operator. For example, you can’t overload the modulus operator (%) so that it can be used with a single operand.
    使用运算符时不能违反运算符原来的句法规则。例如,不能将求模运算符 % 重载成使用一个操作数。

  • Similarly, you can’t alter operator precedence. So if you overload the addition operator to let you add two classes, the new operator has the same precedence as ordinary addition.
    同样,不能修改运算符的优先级。因此,如果将加号运算符重载成将两个类相加,则新的运算符与原来的加号具有相同的优先级。

  • You can’t create new operator symbols. For example, you can’t define an operator**() function to denote exponentiation.
    不能创建新运算符。例如,不能定义 operator**() 函数来表示求幂。

  • 不能重载下面的运算符:

OperatorDescription
sizeofThe sizeof operator
.The membership operator
.*The pointer-to-member operator
::The scope-resolution operator
?:The conditional operator
typeidAn RTTI operator
const_castA type cast operator
dynamic_castA type cast operator
reinterpret_castA type cast operator
static_castA type cast operator

Most of the operators can be overloaded by using either member or nonmember functions. However, you can use only member functions to overload the following operators.
大多数运算符都可以通过成员或非成员函数进行重载,但下面的运算符只能通过成员函数进行重载。

OperatorDescription
=Assignment operator
()Function call operator
[]Subscripting operator
->Class member access by pointer operator
  • 可重载的运算符

在这里插入图片描述

2.3. 重载运算符 -*

  • time.h
// Time class before operator overloading
#ifndef TIME_H_
#define TIME_H_

class Time {
private:
	int hours;
	int minutes;

public:
	Time();
	Time(const int h, const int m = 0);
	~Time();

	void AddMinutes(const int m);
	void AddHours(const int h);
	void Reset(const int h = 0, const int m = 0);
	Time operator+(const Time & time) const;
	Time operator-(const Time & time) const;
	Time operator*(const double factor) const;
	void Show() const;
};

#endif

  • time.cpp
#include <iostream>

#include "time.h"

Time::Time() {
	std::cout << "Time::Time()" << std::endl;
	hours = minutes = 0;
}

Time::Time(const int h, const int m) {
	std::cout << "Time::Time(const int h, const int m): h=" << h << ", m=" << m << std::endl;
	hours = h;
	minutes = m;
}

Time::~Time() {
	std::cout << "Time::~Time(): hours=" << hours << ", minutes=" << minutes << std::endl;
}

void Time::AddMinutes(const int m) {
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::AddHours(const int h) {
	hours += h;
}

void Time::Reset(const int h, const int m) {
	hours = h;
	minutes = m;
}

Time Time::operator+(const Time & time) const {
	std::cout << "Time::operator+(const Time & time)" << std::endl;
	Time sum;
	sum.minutes = minutes + time.minutes;
	sum.hours = hours + time.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

Time Time::operator-(const Time & time) const {
	std::cout << "Time::operator-(const Time & time)" << std::endl;
	Time diff;
	const int tot1 = time.minutes + 60 * time.hours;
	const int tot2 = minutes + 60 * hours;
	diff.minutes = (tot2 - tot1) % 60;
	diff.hours = (tot2 - tot1) / 60;
	return diff;
}

Time Time::operator*(const double factor) const {
	std::cout << "Time::operator*(const double factor)" << std::endl;
	Time result;
	const long total_minutes = hours * factor * 60 + minutes * factor;
	result.hours = total_minutes / 60;
	result.minutes = total_minutes % 60;
	return result;
}


void Time::Show() const {
	std::cout << hours << " hours, " << minutes << " minutes";
}

  • sample.cpp
#include <iostream>

#include "time.h"

int main() {
	{
		Time weeding(4, 35);
		Time waxing(2, 47);

		Time total;
		Time diff;
		Time yongqiang;

		std::cout << "\nweeding time = ";
		weeding.Show();
		std::cout << std::endl;

		std::cout << "waxing time = ";
		waxing.Show();
		std::cout << std::endl << std::endl;

		total = weeding + waxing;  // use operator+()
		std::cout << "total work time = ";
		total.Show();
		std::cout << std::endl << std::endl;

		diff = weeding - waxing;  // use operator-()
		std::cout << "weeding time - waxing time = ";
		diff.Show();
		std::cout << std::endl << std::endl;

		yongqiang = total * 1.5;  // use operator+()
		std::cout << "adjusted work time = ";
		yongqiang.Show();
		std::cout << std::endl << std::endl;
	}

	return 0;
}

在这里插入图片描述

Time::Time(const int h, const int m): h=4, m=35
Time::Time(const int h, const int m): h=2, m=47
Time::Time()
Time::Time()
Time::Time()

weeding time = 4 hours, 35 minutes
waxing time = 2 hours, 47 minutes

Time::operator+(const Time & time)
Time::Time()
Time::~Time(): hours=7, minutes=22
Time::~Time(): hours=7, minutes=22
total work time = 7 hours, 22 minutes

Time::operator-(const Time & time)
Time::Time()
Time::~Time(): hours=1, minutes=48
Time::~Time(): hours=1, minutes=48
weeding time - waxing time = 1 hours, 48 minutes

Time::operator*(const double factor)
Time::Time()
Time::~Time(): hours=11, minutes=3
Time::~Time(): hours=11, minutes=3
adjusted work time = 11 hours, 3 minutes

Time::~Time(): hours=11, minutes=3
Time::~Time(): hours=1, minutes=48
Time::~Time(): hours=7, minutes=22
Time::~Time(): hours=2, minutes=47
Time::~Time(): hours=4, minutes=35
请按任意键继续. . .

References

[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] C++ Primer Plus, 6th Edition, https://www.informit.com/store/c-plus-plus-primer-plus-9780321776402

  • Operator Overloading
  • Time on Our Hands: Developing an Operator Overloading Example

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

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

相关文章

特征融合篇 | YOLOv10改进之在Neck网络中添加加权双向特征金字塔BiFPN

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。在计算机视觉任务中&#xff0c;特征金字塔网络&#xff08;FPN&#xff09;是一种常用的方法&#xff0c;它通过构建不同尺度的特征图来捕获不同尺度的目标。然而&#xff0c;传统的FPN存在一些缺点&#xff0c;如特征融合…

05STM32EXIT外部中断中断系统

STM32EXIT外部中断&中断系统 中断系统中断触发条件&#xff1a;中断处理流程和用途&#xff1a; STM32中断NVIC嵌套中断向量控制器基本结构 中断系统 中断触发条件&#xff1a; 对外部中断来说&#xff0c;可以是引脚发生了电平跳变 对定时器来说&#xff0c;可以是定时的…

【最强八股文 -- 计算机网络】【快速版】WWW 构建技术 (3 项)

1.HTML(HyperText Markup Language):作为页面的文本标记语言 2.HTTP(HyperTextTransfer Protocol):文档传递协议 3.URL(Uniform Resource Locator):指定文档所在地址 HTTPS 和 HTTP 的区别: HTTP: 以明文的方式在网络中传输数据&#xff0c;HTTPS 解决了HTTP 不安全的缺陷&…

.NET周刊【7月第1期 2024-07-07】

国内文章 学习.NET 8 MiniApis入门 https://www.cnblogs.com/hejiale010426/p/18280441 MiniApis是ASP.NET Core中的轻量级框架&#xff0c;用最少的代码和配置创建HTTP API。其特点包括简洁明了、性能卓越、灵活多变、易于学习使用&#xff0c;并与ASP.NET Core生态系统完美…

matlab仿真 模拟调制(上)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第五章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 1.幅度调制 clear all ts0.0025; %信号抽样时间间隔 t0:ts:10-ts;%时间矢量 fs1/ts;%抽样频率 dffs/length(t); %fft的频率分…

ApiFox或postman怎么用params类型传输json或集合+json的String类型

你是否碰见过这样的接口? post请求然后传输的参数都要和查询时一样以param形式传参数,那String什么的都好说,传就直接进后台了,那json呢,集合呢,是不是直接给你返400呢. 1.传json如何处理 那我们看看怎么实现,如果你要传json数据,那需要将特殊字符转义,也叫url转码,否则传不…

JRT打印药敏报告

最近没写jrt系列博客&#xff0c;不是中途而废了。而是在写微生物系统。今天终于把微生物大体完成了&#xff0c;伴随着业务的实现&#xff0c;框架趋于完善和稳定。构建一套完美而强大的打印体系一直是我的理想&#xff0c;从最开始C#的winform打印控件到刚接触bs时候用js打印…

R包:reticulate R对python的接口包

介绍1 R和python是两种不同的编程语言&#xff0c;前者是统计学家发明并且服务数学统计计算&#xff0c;后者则是最万能的胶水语言。随着大数据时代的到来&#xff0c;两者在数据分析领域存在越来越多的共同点且可以相互使用&#xff0c;为了破解二者的编程壁垒&#xff0c;CR…

✅小程序申请+备案教程

##red## &#x1f534; 大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff0c;雄雄的小课堂。 零、注意事项 需要特别注意的是&#xff0c;如果公司主体的微信公众号已经交过300块钱的认证费了的话&#xff0c;注册小程序通过公众号来注册&#xff0c;可以免…

OpenCV 寻找棋盘格角点及绘制

目录 一、概念 二、代码 2.1实现步骤 2.2完整代码 三、实现效果 一、概念 寻找棋盘格角点&#xff08;Checkerboard Corners&#xff09;是计算机视觉中相机标定&#xff08;Camera Calibration&#xff09;过程的重要步骤。 OpenCV 提供了函数 cv2.findChessboardCorners…

【Python】 已解决:ModuleNotFoundError: No module named…

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named… 一、分析问题背景 在使用Python进行开发时&#xff0c;有时会遇到“ModuleNotFoundError: No module named…”这样的…

做突破交易时,需要注意的进场细节有哪些?

突破交易揭示了市场未来的走向。 在这种情况下&#xff0c;面对市场时我们应该如何入场操作呢&#xff1f;接下来&#xff0c;让我们来细化一下实施的具体步骤。 01. 在交易中&#xff0c;周期的考量比价格突破更为关键。 当价格突破发生时&#xff0c;市场的平静被打破&#x…

非线性系列(三)—— 非线性求解器算法分类

1. 总体认知 CAE中的非线性方程组求解主要依赖牛顿法&#xff08;及牛顿法的变体&#xff09;&#xff0c;步骤如下 以线搜索方法为例&#xff0c;流程如下: 2. 方法分类 适用范围大类小类描述牛顿法雅可比矩阵难获取拟牛顿法 Broyden&#xff08;Secant method&#xff09;、…

评估测试用例有效性 5个方面

评估测试用例的有效性是确保软件测试活动能够达到预期目标的关键步骤&#xff0c;有助于测试团队优化测试计划&#xff0c;提高测试效率&#xff0c;减少返工&#xff0c;节省成本。如果缺乏对测试用例的有效性评估&#xff0c;可能会导致测试用例无法覆盖关键功能点&#xff0…

客户​青海地区图像识别,云拍产品实施安装#数采物联

客户青海地区图像识别&#xff0c;云拍产品实施安装。#数采物联。 客户青海地区图像识别&#xff0c;云拍产品实施安装。#数采物联。

系统服务综合作业

首先配置自动挂载 服务器的/rhce 自动挂载在客服端的/nfs/rhce 首先在服务器进行配置 dnf install nfs-utils -y [rootlocalhost ~]# vim /etc/exports [rootlocalhost ~]# firewall-cmd --permanent --add-servicenfs success [rootlocalhost ~]# firewall-cmd --permanen…

【人工智能】Transformers之Pipeline(概述):30w+大模型极简应用

​​​​​​​ 目录 一、引言 二、pipeline库 2.1 概述 2.2 使用task实例化pipeline对象 2.2.1 基于task实例化“自动语音识别” 2.2.2 task列表 2.2.3 task默认模型 2.3 使用model实例化pipeline对象 2.3.1 基于model实例化“自动语音识别” 2.3.2 查看model与task…

数据结构——约瑟夫环C语言链表实现

约瑟夫环问题由古罗马史学家约瑟夫&#xff08;Josephus&#xff09;提出&#xff0c;他参加并记录了公元66—70年犹太人反抗罗马的起义。在城市沦陷之后&#xff0c;他和40名死硬的将士在附近的一个洞穴中避难。起义者表示“宁为玉碎不为瓦全”&#xff0c;约瑟夫则想“留得青…

双栈实现一个队列

两个栈可实现将列表倒序&#xff1a;设有含三个元素的栈 A [1,2,3] 和空栈 B [] 。若循环执行 A 元素出栈并添加入栈 B &#xff0c;直到栈 A 为空&#xff0c;则 A [] , B [3,2,1] &#xff0c;即栈 B 元素为栈 A 元素倒序。 利用栈 B 删除队首元素&#xff1a;倒序后&am…