C++类与对象深度解析(五):友元机制、内部类与匿名对象的高级应用

news2024/9/19 17:06:34

文章目录

  • C++类和对象——全面指南
    • 前言
      • 4. 友元详解
        • 4.1 友元的基本概念
      • 4.2 友元函数
        • 示例代码:友元函数访问两个类的私有成员
        • 输出:
      • 4.3 友元类
        • 示例代码:友元类的使用
        • 输出:
      • 4.4 友元的特性与限制
      • 4.5 友元函数与类的实际应用
        • 示例:使用友元进行类间合作
        • 输出:
      • 总结
      • 5. 内部类详解
        • 5.1 内部类的基本概念
      • 5.2 内部类的使用示例
        • 示例代码
        • 输出:
      • 5.3 封装与访问权限
        • 示例:将内部类放在 `private` 区域
        • 输出:
      • 5.4 内部类的封装与应用场景
        • 场景:内部类作为外部类的专属工具类
        • 输出:
      • 5.5 内部类的友元关系
        • 示例:内部类访问外部类的私有成员
        • 输出:
      • 5.6 应用:求 1 + 2 + 3 + ... + n
        • 示例代码
        • 输出:
      • 总结
      • 6. 匿名对象详解
        • 6.1 匿名对象的基本概念
        • 匿名对象 vs 有名对象
        • 6.2 匿名对象的创建与销毁
        • 示例代码
        • 输出:
      • 6.3 匿名对象的应用场景
        • 6.3.1 匿名对象用于临时调用成员函数
        • 输出:
        • 6.3.2 匿名对象避免对象命名
        • 示例:返回匿名对象
        • 输出:
      • 6.4 匿名对象的注意事项
      • 总结
  • 写在最后

C++类和对象——全面指南

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!

👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!

前言

接上篇【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解

在上一篇博客中,我们详细探讨了C++中的类与对象,包括初始化列表、类型转换、以及静态成员的核心概念。这些内容为我们理解C++中的面向对象编程奠定了坚实的基础。

在本篇博客中,我们将继续深入探讨C++中的高级特性,聚焦于友元、内部类、以及匿名对象等关键概念。这些特性在实际开发中尤为重要,它们不仅能提升代码的可读性与安全性,还能帮助开发者更好地管理复杂的类结构与对象生命周期。通过对这些特性的深入解析,你将能够更灵活地运用C++语言,编写出更高效、易维护的代码。

让我们一同揭开这些高级特性的神秘面纱,进一步提升你的C++编程能力吧!

4. 友元详解

在C++中,友元(friend)提供了一种突破类的访问限定符的机制,使得外部函数或其他类可以访问类的私有(private)受保护的成员(protected)。友元可以是友元函数友元类,而这种友元关系是在类定义中通过关键字 friend 显式声明的。

4.1 友元的基本概念
  • 友元函数:友元函数可以访问类的私有和受保护成员,但它并不是类的成员函数。
  • 友元类:某个类的所有成员函数都可以是另一个类的友元,允许访问该类的私有和受保护成员。
  • 单向关系:友元关系是单向的,如果A类是B类的友元,B类的成员函数可以访问A类的私有成员,但A类不能访问B类的私有成员,除非B类也显式声明A类为友元。
  • 友元的局限性:虽然友元提供了便利,但它打破了类的封装性,增加了类之间的耦合,因此不宜滥用。

4.2 友元函数

友元函数是一个外部函数,但通过友元声明,它可以访问类的私有和受保护的成员。友元函数不属于类的成员函数,它可以在类的任意地方声明,而不受访问限定符(publicprivateprotected)的限制。

示例代码:友元函数访问两个类的私有成员
#include<iostream>
using namespace std;

// 前置声明,避免类A的友元函数不识别类B
class B;

class A {
    // 友元声明,允许函数 func 访问A类的私有成员
    friend void func(const A& aa, const B& bb);

private:
    int _a1 = 1;
    int _a2 = 2;
};

class B {
    // 友元声明,允许函数 func 访问B类的私有成员
    friend void func(const A& aa, const B& bb);

private:
    int _b1 = 3;
    int _b2 = 4;
};

// 友元函数定义,能够访问A和B类的私有成员
void func(const A& aa, const B& bb) {
    cout << "A::_a1: " << aa._a1 << endl;  // 访问A类的私有成员
    cout << "B::_b1: " << bb._b1 << endl;  // 访问B类的私有成员
}

int main() {
    A aa;
    B bb;
    func(aa, bb);  // 调用友元函数,访问A和B类的私有成员

    return 0;
}
输出:
A::_a1: 1
B::_b1: 3

解释

  • 函数 func 被声明为 AB 类的友元,因此它可以访问 A 类和 B 类的私有成员变量 _a1_b1
  • 虽然 func 是一个独立于类的外部函数,但通过友元声明,它获得了访问类的私有数据的权限。

4.3 友元类

友元类允许一个类的所有成员函数访问另一个类的私有和受保护成员。友元类的成员函数并不需要逐一声明为友元,只要类被声明为友元,所有的成员函数都能访问另一个类的私有和受保护成员。

示例代码:友元类的使用
#include<iostream>
using namespace std;

class A {
    // 友元类B声明,允许B类的所有成员函数访问A类的私有成员
    friend class B;

private:
    int _a1 = 1;
    int _a2 = 2;
};

class B {
public:
    // 可以访问A类的私有成员
    void func1(const A& aa) {
        cout << "A::_a1: " << aa._a1 << endl;  // 访问A类的私有成员
        cout << "B::_b1: " << _b1 << endl;     // 访问B类的私有成员
    }

    void func2(const A& aa) {
        cout << "A::_a2: " << aa._a2 << endl;  // 访问A类的私有成员
        cout << "B::_b2: " << _b2 << endl;     // 访问B类的私有成员
    }

private:
    int _b1 = 3;
    int _b2 = 4;
};

int main() {
    A aa;
    B bb;
    bb.func1(aa);  // 通过B类的成员函数访问A类的私有成员
    bb.func2(aa);  // 通过B类的成员函数访问A类的私有成员

    return 0;
}
输出:
A::_a1: 1
B::_b1: 3
A::_a2: 2
B::_b2: 4

解释

  • B 类被声明为 A 类的友元类,因此 B 类的所有成员函数都可以访问 A 类的私有成员 _a1_a2
  • 通过友元类声明,不需要逐个将 B 类的成员函数声明为 A 类的友元,只要 B 类是 A 类的友元,B 类的所有成员函数都可以访问 A 类的私有数据。

4.4 友元的特性与限制

  • 单向关系:友元关系是单向的,如果 AB 的友元,那么 B 类的成员可以访问 A 类的私有成员,但 A 类不能访问 B 类的私有成员,除非 B 类也将 A 类声明为友元。

示例:单向友元关系

class A;

class B {
    friend class A;  // B 声明 A 为友元
private:
    int _b1 = 1;
};

class A {
public:
    void accessB(B& bb) {
        // A 可以访问 B 的私有成员
        cout << "B::_b1: " << bb._b1 << endl;
    }
};

int main() {
    A aa;
    B bb;
    aa.accessB(bb);  // A 类访问 B 的私有成员
    return 0;
}

输出:

B::_b1: 1
  • 不具有传递性:友元关系不具有传递性。如果 AB 的友元,BC 的友元,A 不能访问 C 类的私有成员。

  • 友元增加耦合性:虽然友元机制提供了访问类私有成员的便利,但过度使用友元会导致类与类之间的耦合增加,破坏了类的封装性。因此,友元不宜滥用,应该谨慎使用。


4.5 友元函数与类的实际应用

友元在某些情况下能提供方便,比如当需要两个类之间进行紧密合作时,使用友元可以简化代码,减少冗长的接口设计。

示例:使用友元进行类间合作
#include<iostream>
using namespace std;

class Account;

class Transaction {
public:
    void deposit(Account& account, double amount);
    void withdraw(Account& account, double amount);
};

class Account {
    friend class Transaction;  // 声明 Transaction 类为友元类
public:
    Account(double balance) : _balance(balance) {}

    void showBalance() const {
        cout << "Balance: " << _balance << endl;
    }

private:
    double _balance;
};

void Transaction::deposit(Account& account, double amount) {
    account._balance += amount;  // 直接访问 Account 类的私有成员
}

void Transaction::withdraw(Account& account, double amount) {
    if (amount <= account._balance) {
        account._balance -= amount;
    } else {
        cout << "Insufficient balance" << endl;
    }
}

int main() {
    Account myAccount(1000.0);
    Transaction trans;

    trans.deposit(myAccount, 500.0);  // 存款
    myAccount.showBalance();          // 输出:1500

    trans.withdraw(myAccount, 200.0); // 取款
    myAccount.showBalance();          // 输出:1300

    return 0;
}
输出:
Balance: 1500
Balance: 1300

解释

  • Transaction 类被声明为 Account 类的友元类,因此 Transaction 类的成员函数 depositwithdraw 可以直接访问 Account 类的私有成员 _balance

  • 这种情况下,友元机制简化了类与类之间的合作,不必通过公共接口访问私有数据,减少了不必要的代码冗余。


总结

  • 友元机制在C++中提供了一种打破类封装的方式,允许外部函数或类访问类的私有和受保护成员。它通过friend关键字来声明友元函数或友元类,使得类之间的合作更加简便。
  • 友元函数友元类都有其特定的用途,友元函数可以访问多个类的私有成员,而友元类则使得另一个类的所有成员函数都可以访问当前类的私有数据。
  • 友元关系是单向的,不具有传递性,过度使用友元会破坏类的封装性和增加类的耦合性,应该谨慎使用。

5. 内部类详解

内部类(Nested Class)是指一个类定义在另一个类的内部。在C++中,内部类和外部类是独立的类,尽管它们之间有一定的联系,但内部类不属于外部类的对象,它有自己的内存布局和独立性。使用内部类通常是为了封装和简化类之间的关联。

5.1 内部类的基本概念
  • 独立性:尽管内部类是定义在外部类的内部,但它是一个独立的类。外部类的对象并不包含内部类的对象。也就是说,创建外部类的对象时,并不会自动创建内部类的对象,内部类需要单独实例化。
  • 友元关系:内部类默认是外部类的友元类,这意味着内部类可以访问外部类的私有成员。
  • 封装:使用内部类可以将一些只在外部类内部使用的逻辑封装起来,使代码更加紧凑和可控。内部类可以定义在 privateprotected 访问限定符下,限制其他类对其的访问。

5.2 内部类的使用示例

以下是一个包含内部类的简单示例,展示了如何在外部类中定义内部类,以及如何让内部类访问外部类的私有成员。

示例代码
#include<iostream>
using namespace std;

class A {
private:
    static int _k;  // 外部类的静态成员
    int _h = 1;     // 外部类的非静态成员

public:
    // 定义内部类 B
    class B {
    public:
        // 内部类方法可以访问外部类的私有成员,因为 B 是 A 的友元类
        void foo(const A& a) {
            cout << "A::_k = " << _k << endl;   // 访问外部类的静态成员
            cout << "A::_h = " << a._h << endl; // 访问外部类的非静态成员
        }
    };
};

// 初始化外部类的静态成员
int A::_k = 1;

int main() {
    cout << "Size of A: " << sizeof(A) << endl;  // 输出 A 类的大小

    A::B b;  // 创建内部类 B 的对象

    A aa;    // 创建外部类 A 的对象
    b.foo(aa);  // 使用内部类对象调用其方法,访问外部类的私有成员

    return 0;
}
输出:
Size of A: 4
A::_k = 1
A::_h = 1

解释

  • 内部类 B 被定义在外部类 Apublic 区域中,但它依然是 A 的友元类,可以访问 A 类的私有成员变量 _k_h
  • 创建了 A::B b 来实例化内部类 B,然后通过内部类的成员函数 foo 访问外部类对象的私有成员。
  • sizeof(A) 表示 A 类的大小,由于 A 只有一个整数成员 _h,因此其大小为4字节。

5.3 封装与访问权限

内部类作为外部类的一部分,可以被放置在 privateprotected 访问区域中,这样可以控制内部类的可见性。

示例:将内部类放在 private 区域
#include<iostream>
using namespace std;

class Outer {
private:
    class Inner {  // 内部类定义在 private 区域
    public:
        void display() {
            cout << "Inner class method called." << endl;
        }
    };

public:
    void createInner() {
        Inner in;   // 外部类的方法中可以创建内部类的对象
        in.display();
    }
};

int main() {
    Outer outer;
    outer.createInner();  // 通过外部类的方法调用内部类的方法

    // Outer::Inner in;  // 错误!内部类在 private 区域,外部无法访问

    return 0;
}
输出:
Inner class method called.

解释

  • 在这个例子中,内部类 Inner 定义在 Outer 类的 private 区域,外部类的方法 createInner() 可以创建 Inner 类的对象并调用其方法。
  • 尝试在外部直接访问 Inner 类会导致编译错误,因为它是 private 的。

5.4 内部类的封装与应用场景

使用内部类的一个常见场景是当两个类紧密相关时,可以将一个类封装到另一个类中。这样做的目的是让外部类管理内部类的访问,使得内部类只为外部类所用。

场景:内部类作为外部类的专属工具类
#include<iostream>
using namespace std;

class Manager {
private:
    class Task {
    public:
        void performTask() {
            cout << "Performing task." << endl;
        }
    };

public:
    void assignTask() {
        Task t;  // 外部类方法可以使用内部类
        t.performTask();
    }
};

int main() {
    Manager mgr;
    mgr.assignTask();  // 调用外部类的方法,执行内部类中的任务逻辑

    return 0;
}
输出:
Performing task.

解释

  • 这里,Task 类被封装在 Manager 类的 private 区域,表示 Task 只为 Manager 类服务,外部无法直接访问它。
  • 这是一种封装技术,用于使 Task 类专属于 Manager 类,外部无法创建 Task 对象,只能通过 Manager 类的方法来间接使用它。

5.5 内部类的友元关系

内部类默认是外部类的友元类,这意味着内部类可以访问外部类的私有和受保护成员。这种设计允许内部类和外部类之间进行紧密的合作,使得内部类可以像外部类的成员函数一样访问其内部数据。

示例:内部类访问外部类的私有成员
#include<iostream>
using namespace std;

class Container {
private:
    int _data = 100;

public:
    // 定义内部类
    class Helper {
    public:
        void showData(const Container& c) {
            cout << "Container::_data = " << c._data << endl;  // 访问外部类的私有成员
        }
    };
};

int main() {
    Container c;
    Container::Helper h;  // 创建内部类对象

    h.showData(c);  // 调用内部类的方法,访问外部类的私有成员

    return 0;
}
输出:
Container::_data = 100

解释

  • Helper 类作为 Container 的内部类,默认是 Container 的友元,因此它可以访问 Container 类的私有成员 _data
  • 通过内部类的对象 h,可以调用 showData 方法来访问外部类 Container 的私有数据。

5.6 应用:求 1 + 2 + 3 + … + n

内部类可以用于一些特定场景下的封装和逻辑简化,比如下面的例子中,通过内部类 Sum 来计算 1 到 n 的累加和。

在【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解我们也讲过这一个例子,这里使用内部类更合理

示例代码
#include<iostream>
using namespace std;

class Solution {
    // 内部类 Sum,用于进行累加操作
    class Sum {
    public:
        Sum() {
            _ret += _i;  // 每创建一个对象,累加一次当前的 _i
            ++_i;        // 自增 i
        }
    };

    static int _i;    // 用于计数的静态变量
    static int _ret;  // 用于存储结果的静态变量

public:
    int Sum_Solution(int n) {
        Sum arr[n];  // 创建 n 个 Sum 对象,触发累加逻辑
        return _ret; // 返回累加的结果
    }
};

// 初始化静态变量
int Solution::_i = 1;
int Solution::_ret = 0;

int main() {
    Solution sol;
    cout << "Sum of 1 to 5: " << sol.Sum_Solution(5) << endl;  // 1 + 2 + 3 + 4 + 5 = 15
    return 0;
}
输出:
Sum of 1 to 5: 15

解释

  • 内部类 Sum 在创建对象时会自动进行累加操作,创建 nSum 对象等价于对 1n 进行

累加。

  • 静态变量 _i 用于记录当前的计数,_ret 用于存储累加的结果。

总结

  • 内部类是一种封装机制,允许将类定义在另一个类的内部,从而限制内部类的可见性或封装内部逻辑。内部类与外部类独立,但它默认可以访问外部类的私有成员。
  • 内部类的主要优势是封装性紧密耦合。当一个类主要是为了另一个类服务时,将其设计为内部类可以减少外部依赖和接口冗余。
  • 内部类可以用于实现复杂的逻辑封装、类间的紧密合作、计算封装等多个场景,但应谨慎使用,避免过度增加类的复杂性。

6. 匿名对象详解

匿名对象是C++中的一种特殊对象,和普通的有名对象不同,匿名对象没有名字,仅在表达式中被使用,生命周期非常短暂。它的生命周期只限于当前语句,当语句执行结束后,匿名对象就会自动被销毁并调用析构函数。匿名对象的典型用法是临时定义对象,完成某项任务后立即销毁。


6.1 匿名对象的基本概念
  • 匿名对象的定义:匿名对象是通过直接调用构造函数创建的对象,而没有为其指定名字。形式上,它看起来像 A()A(1) 这样的表达式。

  • 生命周期:匿名对象的生命周期非常短暂,只有在当前表达式结束时存在,表达式执行完毕后,匿名对象立即调用析构函数被销毁。

  • 应用场景:匿名对象通常用于临时性操作,例如快速调用某个对象的成员函数或操作符,而不需要将该对象保存在变量中。

匿名对象 vs 有名对象
  • 有名对象:对象名(实参)

    • 例:A obj(1);
    • 生命周期:与作用域相关,当作用域结束时对象销毁。
  • 匿名对象:类型(实参)

    • 例:A(1);
    • 生命周期:只在当前表达式有效,随后立即销毁。

6.2 匿名对象的创建与销毁

在C++中,通过 A()A(1) 这样的语法直接调用构造函数来创建匿名对象,匿名对象没有名字,生命周期仅限于当前行,结束后立即调用析构函数进行销毁。

示例代码
#include<iostream>
using namespace std;

class A {
public:
    // 构造函数
    A(int a = 0) : _a(a) {
        cout << "A(int a) 构造函数被调用, _a = " << _a << endl;
    }

    // 析构函数
    ~A() {
        cout << "~A() 析构函数被调用, _a = " << _a << endl;
    }

private:
    int _a;
};

int main() {
    A aa1;  // 有名对象 aa1 的创建

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

    // 创建匿名对象并立即销毁
    A();    
    A(1);   

    A aa2(2);  // 有名对象 aa2 的创建,生命周期为整个作用域

    // 匿名对象用于调用函数,完成任务后立即销毁
    Solution().Sum_Solution(10);

    return 0;
}
输出:
A(int a) 构造函数被调用, _a = 0
~A() 析构函数被调用, _a = 0
A(int a) 构造函数被调用, _a = 1
~A() 析构函数被调用, _a = 1
A(int a) 构造函数被调用, _a = 2
~A() 析构函数被调用, _a = 2

解释

  • A()A(1) 创建的是匿名对象,它们在当前语句结束后立即调用析构函数。
  • 有名对象 aa1aa2 是在整个作用域内存在的,它们在作用域结束时调用析构函数。
  • 匿名对象 的使用场景之一是调用某个方法或操作符后立即销毁,不占用额外的资源。

6.3 匿名对象的应用场景

6.3.1 匿名对象用于临时调用成员函数

匿名对象的一个常见应用场景是用来临时调用某个类的成员函数,执行完任务后不需要该对象的存在。例如:

class Solution {
public:
    int Sum_Solution(int n) {
        return n * (n + 1) / 2;
    }
};

int main() {
    // 使用匿名对象调用 Sum_Solution 函数
    int result = Solution().Sum_Solution(10);  // 匿名对象创建后立即销毁
    cout << "Sum of 1 to 10: " << result << endl;
    return 0;
}
输出:
Sum of 1 to 10: 55

解释

  • 匿名对象 Solution() 被创建,用于调用 Sum_Solution 函数。函数调用结束后,匿名对象立即销毁,不再占用资源。
  • 这是一种常见的设计模式,适用于不需要保存对象状态的场景。

6.3.2 匿名对象避免对象命名

在某些情况下,我们不需要为对象命名,只是想要使用对象来执行一些操作,匿名对象可以帮助避免命名冲突或不必要的命名。特别是在返回一个对象并立即使用时,匿名对象是理想的选择。

示例:返回匿名对象
class A {
public:
    A(int a) : _a(a) {
        cout << "A(int a) 构造函数被调用, _a = " << _a << endl;
    }

    ~A() {
        cout << "~A() 析构函数被调用, _a = " << _a << endl;
    }

private:
    int _a;
};

// 函数返回一个匿名对象
A createA() {
    return A(100);  // 返回匿名对象
}

int main() {
    createA();  // 调用 createA 函数,返回的匿名对象立即销毁
    return 0;
}
输出:
A(int a) 构造函数被调用, _a = 100
~A() 析构函数被调用, _a = 100

解释

  • 函数 createA 返回一个匿名对象,返回后立即销毁。
  • 匿名对象在不需要进一步使用的情况下,能够有效减少对象创建和销毁的负担。

6.4 匿名对象的注意事项

  1. 生命周期短暂:匿名对象的生命周期只在当前语句结束时有效,不能跨语句使用匿名对象。如果需要在多行代码中使用对象,必须创建有名对象。

    错误示例:

    A obj = A(1);  // 正确,有名对象 obj
    A(1).foo();    // 匿名对象调用方法
    // A(1);        // 错误:匿名对象无法在下一行使用
    
  2. 编译器解析问题:在C++中,有些语法可能导致编译器误判为函数声明而不是对象创建。因此,注意避免如下情况:

    错误示例:

    A aa1();  // 被误判为函数声明,实际上不是对象的创建
    

    正确用法:

    A aa1(1);  // 明确创建对象
    
  3. 匿名对象的返回值优化(RVO):现代C++编译器通常会对匿名对象进行优化,在返回对象时避免多余的拷贝操作。这种优化称为返回值优化(RVO)


总结

  • 匿名对象是没有名字的临时对象,生命周期非常短暂,通常用于一次性操作,如临时调用成员函数或返回值。
  • 匿名对象在表达式结束后立即调用析构函数销毁,适用于不需要持久化对象的场景。
  • 匿名对象避免了额外的命名和管理开销,在简化代码的同时提高了代码的简洁性和可读性。

写在最后

在本文中,我们详细探讨了C++中几个重要的概念:友元、内部类、以及匿名对象。我们首先介绍了友元机制,它提供了一种打破类封装性的方式,允许外部函数或其他类访问类的私有和受保护成员。虽然友元机制方便了类与类之间的合作,但也增加了类之间的耦合性,因此应谨慎使用。接着,我们探讨了内部类的概念,内部类不仅能帮助封装复杂的逻辑,还能让类与类之间紧密合作,尤其是在封装和简化类之间关联方面发挥了重要作用。最后,我们讨论了匿名对象,作为一种特殊的C++对象,它的生命周期非常短暂,常用于临时调用成员函数或避免对象命名。

通过这篇文章,希望你可以掌握这些高级C++特性,并理解如何在实际应用中使用它们来写出更加高效、简洁且可维护的代码。


以上就是关于C++类与对象深度解析(五):友元机制、内部类与匿名对象的高级应用的内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️

在这里插入图片描述

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

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

相关文章

WAAP解决方案:守护数字时代的安全盾牌

在当今这个数字化、数据驱动的时代&#xff0c;网络安全已成为企业运营中不可或缺的一环。随着Web应用程序和API接口在业务中的广泛应用&#xff0c;其面临的安全威胁也日益复杂多变。为此&#xff0c;WAAP&#xff08;Web Application and API Protection&#xff09;解决方案…

JavaEE:网络编程(UDP)

文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…

字符函数 和 字符串函数 的使用与模拟

前言&#xff1a;在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了⽅便操作字符和字符串&#xff0c;C语⾔标准库中提供了 ⼀系列库函数&#xff0c;接下来我们就学习⼀下这些函数。 目录 1. 字符函数 1.1 字符分类判断函数 1.2 字符转换函数 1.3 练…

Sui主网升级至V1.33.2

其他升级要点如下所示&#xff1a; #19404&#xff1a; 启用对等节点的共识轮次探测。 #19119&#xff1a; 无符号整数现在支持.to_string()方法&#xff0c;例如10u8.to_string()等同于 b”10".to_string()。 GraphQL #18774&#xff1a; 为GraphQL引入.move名称解…

Vue3.0组合式API:依赖注入provide和inject实现跨层组件的通信

1、Prop 逐级透传问题 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用 props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了一棵巨大的组件树&#xff0c;而某个深层的子组件需要一个较远的祖先组件中的部分数据…

数字源表测试IC芯片电性能方案

芯片测试作为芯片设计、生产、封装、测试流程中的重要步骤&#xff0c;是使用特定仪器&#xff0c;通过对待测器件DUT(DeviceUnderTest)的检测&#xff0c;区别缺陷、验证器件是否符合设计目标、分离器件好坏的过程。其中直流参数测试是检验芯片电性能的重要手段之一&#xff0…

JAVA国际版同城货运新纪元货拉拉货运车系统小程序源码

&#x1f69a;国际货运新风尚&#xff0c;同城搬家轻松享 —— 货拉拉货运车系统&#xff0c;全球互联新体验&#x1f30d; &#x1f310;【开篇&#xff1a;跨越国界的货运新篇章】&#x1f310; 在这个全球化的时代&#xff0c;无论是跨国企业还是个人需求&#xff0c;都渴…

Java通信协议——UDP通信协议,模拟聊天室(完整详解,附有代码)

UDP通信协议&#xff0c;模拟聊天室 需求说明 实现客户咨询问题&#xff0c;客服人员答复问题 分析 咨询时&#xff0c;客户是发送方&#xff0c;客服人员是接收方 答复时&#xff0c;客服人员是发送方&#xff0c;客户是接收方&#xff0c;实现思路和咨询时相同 当客户端输入 …

【5G QoS】详解5G QoS端到端工作机制

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

大田上的路径跟踪论文汇总

文章目录 2022Path tracking control method and performance test based on agricultural machinery pose correction&#xff08;Computers and Electronics in Agriculture&#xff09;An optimal goal point determination algorithm for automatic navigation of agricult…

4款AI生成PPT工具推荐,提升工作效率

在如今的工作环境中&#xff0c;PPT制作是许多技术人员不可避免的任务&#xff0c;尤其是在汇报、展示技术方案、以及项目进展时。随着AI技术的快速发展&#xff0c;使用AI生成PPT成为了提高效率的一种新趋势。本文将介绍几款适合程序员、技术人员的AI生成PPT工具&#xff0c;帮…

如何用 HAproxy 实施高可用部署 | OceanBase 实践

背景介绍 最近&#xff0c;我们部署了Oceanbase数据库&#xff08;以下简称OB&#xff09;&#xff0c;并将部分业务迁移至OB中运行。在部署过程中&#xff0c;我们虽然配置了3个OBProxy&#xff0c;但没有为它们设置高可用配置&#xff0c;应用被固定到某一个OBProxy 上&…

通信工程学习:什么是POS无源光分配器

POS&#xff1a;无源光分配器 POS&#xff08;Passive Optical Splitter&#xff0c;无源光分配器&#xff09;是无源光网络&#xff08;Passive Optical Network, PON&#xff09;中的一个重要组成部分&#xff0c;它位于光线路终端&#xff08;OLT&#xff09;和光网络单元&a…

基于Spring Boot的能源管理系统+建筑能耗+建筑能耗监测系统+节能监测系统+能耗监测+建筑能耗监测

介绍 建筑节能监测系统是基于计算机网络、物联网、大数据和数据可视化等多种技术融合形成的一套节能监测系统。 系统实现了对建筑电、水、热&#xff0c;气等能源、资源消耗情况的实时监测和预警、动态分析和评估&#xff0c;为用户建立了科学、系统的节能分析方法&#xff0c…

你天天用微服务还不知道心跳检测机制是什么?

目录标题 1. 心跳检测机制概述2. 心跳检测的具体实现2.1 服务注册与发现示例&#xff1a;Eureka 2.2 心跳包的格式2.3 超时机制 3. 实战中的心跳检测3.1 服务发现与注册中心3.2 定时任务与超时机制3.3 集群管理与协调3.4 故障隔离与恢复 4. 监控与告警5. 具体示例&#xff1a;Z…

制作一个rabbitmq-sdk

目录结构 pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">&l…

VR全景摄影制作中的常见问题及解决方案

随着VR全景摄影技术的普及&#xff0c;越来越多的摄影师和企业开始尝试使用这种方式来展示产品、场景或服务。虽然VR全景摄影有着强大的视觉表现力和沉浸式体验&#xff0c;但在制作过程中也会遇到各种挑战。为了帮助大家更好地掌握VR全景摄影的制作技巧&#xff0c;今天给分享…

STM32 单片机最小系统全解析

STM32 单片机最小系统全解析 本文详细介绍了 STM32 单片机最小系统&#xff0c;包括其各个组成部分及设计要点与注意事项。STM32 最小系统在嵌入式开发中至关重要&#xff0c;由电源、时钟、复位、调试接口和启动电路等组成。 在电源电路方面&#xff0c;采用 3.3V 直流电源供…

【Bug解决】Nacos启动成功,但却无法访问(提示:无法访问此网站,192.168.10.88的响应时间过长)

项目场景&#xff1a; 在虚拟机上通过Docker创建Nacos容器&#xff0c;已经创建成功&#xff0c;查看Nacos启动日志也是成功。但通过端口号加8848/nacos&#xff08;如&#xff1a;http://IP:8848/nacos&#xff09;无法访问到Nacos管理页面。 愿意分析一&#xff1a; 先检查好…

MyISAM引擎介绍

文章目录 特点适用场景不足锁机制表级锁的类型锁的获取和释放锁的等待队列 示例共享锁排他锁READ LOCAL MyISAM是MySQL的一种存储引擎&#xff0c;它以其简单性和高速度而著称。在早期的MySQL版本中&#xff0c;MyISAM广泛使用&#xff0c;尤其是在那些以读操作为主的应用场景中…