C++其他语法..

1.运算符重载

之前有一个案例如下所示 其中我们可以通过add方法将两个点组成一个新的点

class Point {friend Point add(Point, Point);int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}
};
Point add(Point p1, Point p2) {return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = add(p1, p2);p3.display();getchar();return 0;
}

但是有一个想法就是 可不可以直接通过加法运算将两个顶点组成新的点 即Point p3 = p1 + p2
答案是可以的 我们可以通过实现operator+来为加法运算增加新功能
以下案例中 我们通过重载方法operator实现了Point对象的加法运算

class Point {friend Point operator+(Point p1, Point p2);int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}
};
Point operator+(Point p1, Point p2) {return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = p1 + p2;p3.display();getchar();return 0;
}

其实p1 + p2的本质就是调用了operator+(p1, p2)
在这里插入图片描述
我们再来看一下以下这个案例

class Point {friend Point operator+(Point p1, Point p2);int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}
};
Point operator+(Point p1, Point p2) {return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
int main() {Point p1(10, 20);Point p2(20, 30);Point p3(30, 40);Point p4 = p1 + p2 + p3;p4.display();getchar();return 0;
}

我们应该可以知道p1 + p2 + p3的本质其实就是调用了两次operator+
在这里插入图片描述
我们可以对上述operator+方法进行优化 具体改写成
修改原因:1.对象类型做参数时 可能会产生不必要的中间对象 所以尽量使用引用/指针来避免
2.参数用const修饰可以使得参数接受范围更大 因为他可以接收const和非const参数 而非const形参显然只能接收非const实参
基于以上两点原因 有了以下优化代码

Point operator+(const Point& p1, const Point& p2) {return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}

说到这里 我们应该就可以明白拷贝构造函数形参如此写法的原因了
原因有二:1.如果我们的形参是一个对象类型的话 那么当我们调用拷贝构造函数创建一个新对象时 就会无限次的调用该拷贝构造函数 原因在于将实参赋值给形参就会创建新对象 从而调用拷贝构造函数 调用了之后 又会将实参赋值给形参从而调用构造函数 之后就一直重复这个过程 但当我们将对象类型改成引用类型以后 我们就可以杜绝无限调用的现象
2.如果我们传递的实参是const修饰 那么显然非const形参是无法接收这个实参的 所以必须要将形参设计为const修饰 才能接收更大范围的实参

其实对于运算符重载函数而言 我们还可以进一步优化 将其内置于类内部 变成成员函数 这样做的好处是我们可以不用通过友元函数的声明来实现对类内部私有成员的访问 在类内部的成员函数就可以直接访问类内部的私有成员了

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}Point operator+(const Point& p2) {return Point(m_x + p2.m_x, m_y + p2.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);// 相当于调用了p1对象内部的operator+函数 即p1.operator+(p2)Point p3 = p1 + p2;p3.display();getchar();return 0;
}

模仿以上案例 我们可以自己来实现一下减法运算符重载函数 其中p2 - p1的本质就是调用了p2.operator-(p1)

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}Point operator+(const Point& p2) {return Point(m_x + p2.m_x, m_y + p2.m_y);}Point operator-(const Point& p2) {return Point(m_x - p2.m_x, m_y - p2.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = p2 - p1;p3.display();getchar();return 0;
}

但是呢 有一个潜在的问题 我们知道 对一个临时数据赋值是没有任何意义的 因为他马上就要销毁了 而在赋值到销毁的这段过程中完全是发生在当前语句中 所以压根不能被任何人使用
在c++中 允许对一个表达式进行赋值操作的 也允许对对象之间的运算结果进行赋值操作 但是不允许对常量进行赋值操作
表达式中对象之间的运算结果便是一个临时数据(未用一块内存进行储存) 虽然可以对其赋值 但是没有任何意义 所以我们要杜绝这种赋值行为
我们可以将返回值设置成常量 这样表达式的结果就是一个常量 自然而然是不可以对一个常量进行赋值操作的

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) {return Point(m_x - p2.m_x, m_y - p2.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);(p1 + p2) = Point(40, 50);// errorgetchar();return 0;
}

但是一旦运算符重载函数的返回值修改成了常量 那么之前的三数相加或者三数相减的操作就不被允许了 为什么呢 这是因为const对象只能调用const函数 不能调用非const函数的缘故 所以我们需要将运算符重载函数修改成const修饰的函数

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) {return Point(m_x - p2.m_x, m_y - p2.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);Point p3(30, 40);Point p4 = p1 + p2 + p3;// errorgetchar();return 0;
}
class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);Point p3(30, 40);Point p4 = p1 + p2 + p3;// okp4.display();getchar();return 0;
}

除了加法和减法运算 我们还可以实现一下+=运算符的重载函数

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}void operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;}
};
int main() {Point p1(10, 20);Point p2(20, 30);p1 += p2;p1.display();getchar();return 0;
}

但是a += b这个表达式是可以被赋值的 因为表达式的结果是一块内存 所以p1 += p2是可以进行赋值操作的 我们希望可以有+=重载函数有一个返回值 这样由此创建的表达式就可以进行赋值操作了

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}
};
int main() {Point p1(10, 20);Point p2(20, 30);(p1 += p2) = Point(40, 50);p1.display();getchar();return 0;
}

但是 打印的结果不符合我们的预期 因为实际上p1 += p2的结果是一个全新的对象 只不过他拷贝了p1的数据而已 为了防止函数调用完毕局部变量被回收的现象
所以说为了避免中间对象的产生(主要是为了减少内存开销 但是可能会指向一块回收后再次分配的内存)而导致数据的错误 我们需要将返回值改成引用类型的

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}
};
int main() {Point p1(10, 20);Point p2(20, 30);(p1 += p2) = Point(40, 50);p1.display();getchar();return 0;
}

由于+=重载方法中需要修改成员变量 而const函数不能修改 所以+=重载方法是不可以由const修饰的

我们在来看一下==运算符重载函数的实现 但是需要注意的是如果是const对象调用operator ==方法的话 那么该方法只能够是const修饰

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) const {return ((m_x == p2.m_x) && (m_y == p2.m_y));}
};
int main() {Point p1(10, 20);Point p2(20, 30);cout << (p1 == p2) << endl;getchar();return 0;
}

我们实现一下!=运算符重载函数 但是需要注意的是如果是const对象调用operator!=方法的话 那么该方法只能够是const修饰

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) const {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) const {return ((m_x != p2.m_x) || (m_y != p2.m_y));}
};
int main() {Point p1(10, 20);Point p2(20, 30);cout << (p1 != p2) << endl;getchar();return 0;
}

我们实现一下负号运算符重载函数 请注意 负号是不会改变操作数的数值的
既然负号不会改变操作数的数值 那么我们就需要返回一个新建的对象
由于返回值构成的表达式可以被赋值 而赋值操作没有任何意义 所以我们需要禁止赋值 所以用const修饰返回值
如果我们接连使用多次负号 那么就会产生const对象调用的问题 const对象只能够调用const函数 所以我们需要用const修饰函数

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) {return ((m_x != p2.m_x) || (m_y != p2.m_y));}const Point operator-() const {return Point(-m_x, -m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = (-(-p1));p1.display();p3.display();getchar();return 0;
}

我们在来实现一下自增运算符重载函数
这得分成两类 一类是前缀自增运算符重载函数 一类则是后缀自增运算符重载函数 这两类在写法上有所区分 前者就是默认的写法 而后者则是基于默认写法的基础上在参数列表中加入int
我们先来讲讲前缀自增运算符重载函数
由于前缀自增表达式可以被赋值 所以需要有返回值
再者 为了防止产生中间对象而导致数据错乱 所以我们需要让返回值变成引用类型

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) {return ((m_x != p2.m_x) || (m_y != p2.m_y));}const Point operator-() const {return Point(-m_x, -m_y);}Point& operator++() {m_x++;m_y++;return *this;}
};
int main() {Point p1(10, 20);Point p2(20, 30);(++p1) = Point(40, 50);p1.display();getchar();return 0;
}

然后再来讲讲后缀自增运算符重载函数
由于后缀自增表达式可以参与到加法运算中 所以需要返回值Point 但是同时也可以进行赋值运算了
但是由于我的预期是对最新的值进行赋值操作 而不是针对旧值 所以说 我们不能进行赋值操作 所以需要用const修饰返回值

class Point {int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) {return ((m_x != p2.m_x) || (m_y != p2.m_y));}const Point operator-() const {return Point(-m_x, -m_y);}Point& operator++() {m_x++;m_y++;return *this;}const Point operator++(int) {Point old(m_x, m_y);m_x++;m_y++;return old;}
};
int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = p2++ + Point(40, 50);p3.display();getchar();return 0;
}

我们再来实现一下左移运算符重载函数
首先左移运算符重载函数不可以写在类内部 因为这样会导致<<左边必须为对象类型 而真实代码中<<左边必须是cout(cout是一个类对象 是ostream类对象 ) 所以需要将重载方法定义为全局方法 但是我们就需要将该方法声明为友元方法 这样才能够访问类内部的私有成员
再者 重载方法需要返回值 因为<<可以连用 并且<<左边必须是cout对象 所以返回值是ostream类型 为了防止中间对象的产生 所以返回值需要为ostream&引用类型 至于说要不要加上const修饰 通过测试基本类型的cout的赋值操作(比如:cout << 1 = cout) 我们可以知道赋值操作是行不通的 所以我们需要将返回值设置为常量 即用const修饰返回值 而且由于返回值是const的缘故 导致形参中cout也必须是const修饰
我说实话 const只能够修饰成员函数 并不能修饰全局函数(const对象只能调用const成员函数 但是对于全局函数来说 有无const没有任何影响)
并且由于C++内置的cout行为所在的方法中形参cout也是非const修饰 基于这一点 我们都不能把返回值设置为const修饰
至于说 左移运算符重载函数内部要不要写死endl 如果你是想要将endl灵活的布局在cout语句中 那么请不要写死 反之可以写死 而且千万不要有这种想法 就是cout << endl;执行的是我们自定义的这个方法 实际上他执行的是C++内置的行为

class Point {friend ostream& operator<<(ostream& cout, const Point& p);int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) {return ((m_x != p2.m_x) || (m_y != p2.m_y));}const Point operator-() const {return Point(-m_x, -m_y);}Point& operator++() {m_x++;m_y++;return *this;}const Point operator++(int) {Point old(m_x, m_y);m_x++;m_y++;return old;}
};
ostream& operator<<(ostream& cout, const Point& p) {cout << "(" << p.m_x << ", " << p.m_y << ")";return cout;
}
int main() {Point p1(10, 20);Point p2(20, 30);cout << p1 << p2 << endl;getchar();return 0;
}

最后再来实现一下右移运算符重载函数 同样的 由于成员函数要求>>左边必须是对象类型 而不是istream类型 所以我们得将其声明为全局函数
接着 由于C++中内置的cin的行为所在的函数的形参cin是非const修饰 所以编译器为了让我们统一格式 所以也要求我们自定义的方法中形参的cin必须不被const所修饰 所以也就要求我们函数的返回值不被const修饰
我们也不能用const修饰全局函数
由于我们键入数据的行为相当于对指定变量进行修改 所以我们不能够将形参中的对象类型用const修饰 因为常量是不可以修改的

class Point {friend ostream& operator<<(ostream& cout, const Point& p);friend istream& operator>>(istream& cin, Point& p);int m_x;int m_y;
public:Point(int x, int y) : m_x(x), m_y(y){}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}const Point operator+(const Point& p2) const {return Point(m_x + p2.m_x, m_y + p2.m_y);}const Point operator-(const Point& p2) const {return Point(m_x - p2.m_x, m_y - p2.m_y);}Point& operator+=(const Point& p2){m_x += p2.m_x;m_y += p2.m_y;return *this;}bool operator==(const Point& p2) {return ((m_x == p2.m_x) && (m_y == p2.m_y));}bool operator!=(const Point& p2) {return ((m_x != p2.m_x) || (m_y != p2.m_y));}const Point operator-() const {return Point(-m_x, -m_y);}Point& operator++() {m_x++;m_y++;return *this;}const Point operator++(int) {Point old(m_x, m_y);m_x++;m_y++;return old;}
};
ostream& operator<<(ostream& cout, const Point& p) {cout << "(" << p.m_x << ", " << p.m_y << ")";return cout;
}
istream& operator>>(istream& cin, Point& p) {cin >> p.m_x;cin >> p.m_y;return cin;
}
int main() {Point p1(10, 20);Point p2(20, 30);cin >> p1 >> p2;cout << p1 << p2 << endl;getchar();return 0;
}

我们在自定义对象类型的相关运算符的重载函数时 优先考虑成员函数 不行在定义为全局函数

那么为什么对于刚才的左移运算符重载函数和右移运算符重载函数 他们的返回值既然都是非const 那理应可以进行赋值操作 为什么反而不行 这是因为在ostream/istream类中 赋值运算符重载函数是一个私有的函数 不可访问
从这个解答 我们也可以得出一个思路:
之前的对象拷贝操作如果没有自定义拷贝构造函数的话 那么就得对所有的成员进行赋值操作 但是如果不想要对所有的成员赋值的话 那么我们也可以通过拷贝构造函数进行部分成员的赋值 但是如果连拷贝构造函数都没有的话 那么我们也可以在类中自定义一个赋值运算符重载函数已完成部分成员的赋值操作

总结一下 对于以上重载函数的书写 有个大致的思路:
首先我们可以将基本类型的解决方法代入到对象类型的程序流程中
接着我们需要判断是否需要返回值 这取决于我们是否需要连用、赋值或者参与运算符等其他操作
接着需要判断一下返回值是否需要设置为引用类型 如果没有引用类型会使得预期出现偏差的话 那么我们就需要将返回值设计为引用类型
接着如果返回值确定为不可赋值的话 那么显然为常量 所以返回值需要用const修饰
然后函数需不需要用const修饰取决于你是否需要通过const对象去调用成员函数 因为对于const对象而言 他只可以调用const修饰的成员函数 但是对于全局函数 有无const不影响

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十四.PyEcharts基础学习

目录 1-PyEcharts介绍 优点&#xff1a; 安装: 官方文档&#xff1a; 2-PyEcharts快速入门 2.1 第一个图表绘制 2.2 链式调用 2.3 opeions配置项 2.4 渲染图片文件 2.5 使用主题 3-PyEcharts配置项 3.1 初始化配置项InitOpts InitOpts 3.2 全局配置项set_global_o…

SQLBolt,一个练习SQL的宝藏网站

知乎上有人问学SQL有什么好的网站&#xff0c;这可太多了。 我之前学习SQL买了本SQL学习指南&#xff0c;把语法从头到尾看了个遍&#xff0c;但仅仅是心里有数的程度&#xff0c;后来进公司大量的写代码跑数&#xff0c;才算真真摸透了SQL&#xff0c;知道怎么调优才能最大化…

时序数据库IoTDB:功能详解与行业应用

一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前&#xff0c;先了解一下何谓时序数据。 时序数据&#xff0c;也称为时间序列数据&#xff0c;是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…

基于Arduino IDE 野火ESP8266模块 文件系统LittleFS 的开发

一、文件系统LittleFS的介绍 LittleFS是一个为微控制器设计的轻量级、可靠且高性能的文件系统。它专为嵌入式设备打造&#xff0c;拥有占用空间小、对硬件要求低的特点&#xff0c;同时保证在断电情况下数据的完整性和稳定性。 1.设计与特点 LittleFS的设计旨在提供嵌入式系统所…

Pytorch for training1——read data/image

blog torch.utils.data.Dataset create dataset with class torch.utils.data.Dataset automaticly import torch from torch.utils.data import Datasetclass MyDataset(Dataset):def __init__(self, data):self.data datadef __getitem__(self, index):# 根据索引获取样本…

数据可视化高级技术(Echarts)

目录 &#xff08;一&#xff09;数据可视化概念及Echarts基础知识 数据可视化的好处&#xff1a; 数据可视化的目标 数据可视化的基本流程 &#xff08;二&#xff09;数据图表 类别比较图表&#xff1a; 数据关系图表&#xff1a; 数据分布图表&#xff1a; 时间序列…

智能文档合规检测系统:在央企国企招标采购领域的应用

一、背景介绍 在央企国企采购过程中&#xff0c;合规性是一个不可忽视的重要方面。采购方需要确保供应商的资质、业绩、规模等条件符合采购要求&#xff0c;同时避免设置不合理的条件限制或排斥潜在供应商。为了提高采购效率和确保合规性&#xff0c;智能文档合规检测系统应运…

网页的血液——javascript

JavaScript 基础知识概述 1. JavaScript 介绍 JavaScript 是一种高级的、解释型的编程语言&#xff0c;它是一种基于对象的、事件驱动的语言&#xff0c;它允许开发者创建动态的网页。JavaScript 是一种脚本语言&#xff0c;它可以嵌入到 HTML 中&#xff0c;或者作为外部文件…

YOLOv9改进策略 :主干优化 | 无需TokenMixer也能达成SOTA性能的极简ViT架构 | CVPR2023 RIFormer

💡💡💡本文改进内容: token mixer被验证能够大幅度提升性能,但典型的token mixer为自注意力机制,推理耗时长,计算代价大,而RIFormers是无需TokenMixer也能达成SOTA性能的极简ViT架构 ,在保证性能的同时足够轻量化。 💡💡💡RIFormerBlock引入到YOLOv9,多个数…

ADS-B及雷达显示终端8.4

#更新内容# 本次软件更新内容不少&#xff0c;但可见部分不多。主要更新集中的系统后台部分。后台更新内容包括&#xff1a; #后台更新内容# 1、增加了对部分特殊雷达编码格式的支持。应甲方要求&#xff0c;对部分国产雷达及其特殊的雷达编码协议进行了支持&#xff0c;增加了…

OpenHarmony无人机MAVSDK开源库适配方案分享

MAVSDK 是 PX4 开源团队贡献的基于 MavLink 通信协议的用于无人机应用开发的 SDK&#xff0c;支持多种语言如 C/C、python、Java 等。通常用于无人机间、地面站与通信设备的消息传输。 MAVLink 是一种非常轻量级的消息传递协议&#xff0c;用于与无人机&#xff08;以及机载无…

【好书推荐4】图机器学习

【好书推荐4】图机器学习 写在最前面编辑推荐内容简介作者简介目录前言/序言本书读者内容介绍 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能…

分月饼 java题解

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in); int m sc.nextInt(); // 读取员工数量mint n sc.nextInt(); // 读取月饼数量n// 调用distribute方法并打印返回的分配方法总数//先默认每人分一个…

SmartChart的部署以及可能遇见的报错解决方案

简介 数据可视化是一种将数据转化为图形的技术&#xff0c;可以帮助人们更好地理解和分析数据。但是&#xff0c;传统的数据可视化开发往往需要编写大量的代码&#xff0c;或者使用复杂的拖拽工具&#xff0c;不仅耗时耗力&#xff0c;而且难以实现个性化的需求。有没有一种更…

SwiftUI Swift 显示隐藏系统顶部状态栏

Show me the code // // TestHideSystemTopBar.swift // pandabill // // Created by 朱洪苇 on 2024/4/1. //import SwiftUIstruct TestHideSystemTopBar: View {State private var isStatusBarHidden falsevar body: some View {Button {withAnimation {self.isStatusBa…

67、yolov8目标检测和旋转目标检测算法batchsize=1/6部署Atlas 200I DK A2开发板上

基本思想:需求部署yolov8目标检测和旋转目标检测算法部署atlas 200dk 开发板上 一、转换模型 链接: https://pan.baidu.com/s/1hJPX2QvybI4AGgeJKO6QgQ?pwd=q2s5 提取码: q2s5 from ultralytics import YOLO# Load a model model = YOLO("yolov8s.yaml") # buil…

VUE3——生命周期

Vue3.0中可以继续使用Vue2.x中的生命周期钩子&#xff0c;但有有两个被更名&#xff1a; beforeDestroy改名为 beforeUnmountdestroyed改名为 unmounted Vue3.0也提供了 Composition API 形式的生命周期钩子&#xff0c;与Vue2.x中钩子对应关系如下&#xff1a; beforeCreate&g…

vitess执行计划缓存 测试

打开执行计划器缓存&#xff1a; sysbench /usr/local/share/sysbench/oltp_write_only.lua --mysql-host127.0.0.1 --mysql-port15306 --mysql-userroot --mysql-password --mysql-dbcustomer --report-interval10 100s sysbench /usr/local/share/sysbench/oltp_read_only.l…

有哪些AI智能写作软件?七款自动写作神器,建议收藏

AI智能写作软件的发展&#xff0c;为广大写作者提供了便捷高效的创作工具。如今市场上涌现出了许多优秀的AI智能写作软件&#xff0c;它们各自具备独特的特点和功能&#xff0c;为写作者们带来了全新的写作体验。以下将介绍八款备受推崇的自动写作神器&#xff0c;让我们一起来…

淘宝店铺如何从1688一键铺货?官方授权接口,可满足多样化上货需求

此API目前支持以下基本接口&#xff1a; item_get 获得1688商品详情item_search 按关键字搜索商品item_search_img 按图搜索1688商品&#xff08;拍立淘&#xff09;item_search_suggest 获得搜索词推荐item_fee 获得商品快递费用seller_info 获得店铺详情item_search_shop 获得…