C++初窥门径

news2025/7/13 14:56:18

const关键字 

一、const关键字 
  1. 修饰成员变量

    • 常成员变量必须通过构造函数的初始化列表进行初始化,且初始化后不可修改。

    • 示例

      class Student { 
          private: const int age; // 常成员变量 
      public: Student(string name, int age) : age(age) { ... }
       };
  2. 修饰成员函数

    • 常成员函数

      • 不能修改类的成员变量(编译时检查)。

      • 可以与普通成员函数构成重载,常对象只能调用常成员函数。

    • 示例

      class Student {
      public:
          const void show() { ... }          // 版本1:返回值为const void
          const void show() const { ... }    // 版本2:返回值为const void,且是const成员函数
          void show() const { ... }          // 版本3:返回值为void,且是const成员函数
          void show() { ... }                // 版本4:普通成员函数
      
      private:
          std::string name;
          int age;
      };
      
      const Student stu("Alice", 20);
      stu.show();  // 调用常成员函数版本
  3. 修饰对象

    • 常对象

      • 对象初始化后不可修改成员变量。

      • 只能调用常成员函数。

    • 示例

      const Student stu("Bob", 18);
      // stu.setAge(19);  // 错误:常对象不可修改成员变量
      stu.show();         // 正确:调用常成员函数
二、staticconst修饰构造函数和析构函数
  1. 构造函数

    • static修饰

      • 构造函数用于初始化对象实例,而static成员属于类层级,与对象实例化机制冲突。

      • 禁止:C++语法规定构造函数不能是static

    • const修饰

      • 构造函数需要修改对象状态(初始化成员变量),与const的不可修改语义矛盾。

      • 禁止:构造函数不能声明为const

  2. 析构函数

    • static修饰

      • 析构函数与对象生命周期绑定,而static成员属于类层级,无法处理具体实例的资源释放。

      • 禁止:析构函数不能是static

    • const修饰

      • 析构函数需要释放资源(如动态内存),而const限制成员变量的修改。

      • 禁止:析构函数不能声明为const

三、staticconst修饰成员变量和函数
  1. 成员变量

    • static const成员变量

      • 允许同时使用,表示类层级的常量(所有对象共享同一值)。

      • 必须在类外初始化(C++11后支持类内初始化)。

      • 示例

        class Math {
        public:
            static const double PI = 3.14159;  // 类内初始化(C++11)
        };
  2. 成员函数

    • staticconst同时修饰

      • 无意义static成员函数不关联对象实例(无this指针),而const要求不修改对象状态。

      • 禁止:C++语法不允许static成员函数声明为const

四、关键对比与注意事项
场景const修饰static修饰
成员变量必须初始化,不可修改类层级变量,所有对象共享
成员函数不能修改成员变量,支持重载this指针,不能访问非静态成员
对象只能调用常成员函数不适用(static不修饰对象)
构造函数/析构函数禁止(需修改对象状态)禁止(与对象生命周期绑定)

友元(Friend)

一、 友元(Friend)

1. 核心概念

  • 友元函数:允许外部普通函数访问类的私有成员,需在类内用 friend 声明。

  • 友元成员函数:允许另一个类的某个成员函数访问当前类的私有成员,需在类内声明该成员函数为友元。

  • 友元类:允许另一个类的所有成员函数访问当前类的私有成员,需在类内声明友元类。

2. 特点

  • 单向性:友元关系不可逆(若类A是类B的友元,类B不自动成为类A的友元)。

  • 无继承性:基类的友元不是派生类的友元。

  • 无传递性:若类A是类B的友元,类B是类C的友元,类A不自动成为类C的友元。

3. 应用场景

  • 运算符重载(如 operator<< 用于输出)。

  • 跨类协作(如矩阵类与向量类共享数据)。

  • 工具函数需要访问私有成员时(如调试函数)。

4. 示例代码

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

// 友元函数
class Student {
private:
    string name;
    int age;
public:
    Student(const string &n, int a) : name(n), age(a) {}
    friend void printStudent(const Student& s); // 声明友元函数
};

void printStudent(const Student& s) {
    cout << "Name: " << s.name << ", Age: " << s.age << endl; // 直接访问私有成员
}

// 友元类
class Display {
public:
    void show(const Student& s);
};

class Student {
private:
    string name;
    int age;
public:
    Student(const string &n, int a) : name(n), age(a) {}
    friend class Display; // 声明友元类
};

void Display::show(const Student& s) {
    cout << "Name: " << s.name << ", Age: " << s.age << endl; // 直接访问私有成员
}

// 补充一个友元成员函数
class Student {
private:
    string name;
    int age;
public:
    Student(const string &n, int a) : name(n), age(a) {}
    friend class Display; // 声明友元类
    friend void compareStudents(const Student& s1, const Student& s2); // 声明友元成员函数
};

// 定义友元成员函数,比较两个Student对象的年龄
void compareStudents(const Student& s1, const Student& s2) {
    if (s1.age > s2.age) {
        cout << s1.name << " is older than " << s2.name << endl;
    } else if (s1.age < s2.age) {
        cout << s2.name << " is older than " << s1.name << endl;
    } else {
        cout << s1.name << " and " << s2.name << " are the same age" << endl;
    }
}

int main() {
    Student s1("Alice", 20);
    Student s2("Bob", 22);

    // 使用友元函数
    printStudent(s1); // 输出: Name: Alice, Age: 20

    // 使用友元类
    Display d;
    d.show(s2); // 输出: Name: Bob, Age: 22

    // 使用友元成员函数
    compareStudents(s1, s2); // 输出: Bob is older than Alice

    return 0;
}

运算符重载(Operator Overloading)

一、运算符重载(Operator Overloading)

1. 核心概念

  • 定义:赋予运算符对自定义类类型对象的功能。

  • 格式返回类型 operator运算符(参数列表)

  • 形式

    • 非成员函数:通常声明为友元以访问私有成员。

    • 成员函数:隐含 this 指针,左操作数为当前对象。

2. 常见运算符重载规则

  • 加法运算符(+)成员函数

    String String::operator+(const String &op2){
        int len = strlen(this->str)+strlen(op2.str)+1;
        String newStr;
        newStr.str = new char[len];
        strcpy(newStr.str,this->str);
        strcat(newStr.str,op2.str);
        return newStr;
    }
  • 自增运算符(++)

    • 前置++String& operator++();

    • 后置++String operator++(int);(通过哑元参数区分)

  • 下标运算符([])

    char &String::operator[](int index)const{
        //检查索引是否越界,必须满足在固定的长度内
        if (index < 0 || index >= this->size) {
            static char nullChar = '\0'; // 定义一个静态字符
            return nullChar; // 返回静态字符的引用
        }
        return this->str[index];
    }

3. 关键注意事项

  • 内存管理:运算符重载中若涉及动态内存(如字符串拼接),需实现深拷贝。

  • 返回值优化:返回临时对象时,优先通过构造函数优化(如 return String(buffer);)。

  • 异常处理:下标访问需检查索引范围,防止越界。

4. 示例代码

// 加法运算符重载(非成员函数)
String operator+(const String& a, const String& b) {
    char* buffer = new char[a.length + b.length + 1];
    strcpy(buffer, a.str);
    strcat(buffer, b.str);
    String result(buffer);
    delete[] buffer;
    return result;
}

// 自增运算符重载(成员函数)
String& String::operator++() { // 前置++
    for (char* p = str; *p; p++) (*p)++;
    return *this;
}

String String::operator++(int) { // 后置++
    String temp(*this); // 调用拷贝构造函数
    ++(*this);          // 调用前置++
    return temp;
}

2. 实现String类的下标运算符重载

char &String::operator[](int index)const{
    //检查索引是否越界,必须满足在固定的长度内
    if (index < 0 || index >= this->size) {
        static char nullChar = '\0'; // 定义一个静态字符
        return nullChar; // 返回静态字符的引用
    }
    return this->str[index];
}
二、赋值运算符(=)重载
  1. 核心作用
    实现对象间的深拷贝,避免浅拷贝导致的内存重复释放或泄漏。

  2. 实现要点

    • 自赋值检查:防止 a = a 导致内存错误。

    • 释放旧内存:赋值前需释放当前对象的资源。

    • 深拷贝新内存:重新分配内存并复制内容。

  3. 代码示例

    String &String::operator=(const String &obj)
    {
        if (this != &obj)
        { // Exclude the scenario where this points to obj
            if (this->str != NULL)
            {
                delete[] this->str;
            }
            if (obj.str != NULL)
            {
                int len = strlen(obj.str) + 1;
                this->str = new char[len];
                strcpy(this->str, obj.str);
            }
        }
        return *this;
    }
  4. 注意事项

    • 必须为成员函数:C++规定赋值运算符只能通过成员函数重载。

    • 默认赋值运算符的陷阱:默认实现为浅拷贝,需手动重载以支持深拷贝。

三、左移运算符(<<)重载
  1. 核心作用
    支持自定义类的输出流操作(如 cout << obj)。

  2. 实现要点

    • 声明为友元函数:以访问类的私有成员。

    • 返回 ostream&:支持链式调用(如 cout << a << b)。

  3. 代码示例

    两种实现方法
    1、
    ostream &operator<<(ostream &os, const String &obj)
    {
        if (obj.str)
        {
            os << obj.str;
        }
        return os;
    }
    2、
    class String {
    private:
        char* str;
    public:
        friend ostream& operator<<(ostream& os, const String& obj);
    };
    
    ostream& operator<<(ostream& os, const String& obj) {
        if (obj.str != nullptr) {
            os << obj.str;
        }
        return os;  // 返回流引用以支持链式调用
    }
  4. 注意事项

    • 输入运算符(>>)同理:需处理输入流并修改对象状态,通常声明为友元。

四、不能被重载的运算符
运算符不可重载原因
.成员访问运算符,重载会破坏语言基础结构。
::域运算符,属于编译时解析的语法结构。
sizeof计算对象大小,编译时确定,无法动态重载。
?:三目运算符,逻辑复杂且可能引发歧义。
.* 和 ->*成员指针访问运算符,语法特殊且用途有限。
五、运算符重载的通用规则
  1. 语法限制

    • 只能重载C++已有的运算符,不可创建新运算符(如 **)。

    • 不能改变运算符的优先级、结合性或操作数个数(如 + 始终为双目运算符)。

  2. 函数形式

    • 成员函数:适用于左操作数为当前类对象(如 a + b)。

    • 友元函数:适用于左操作数为其他类型(如 cout << obj)。

  3. 特殊运算符重载

    • 自增/自减运算符

      String& operator++();    // 前置++
      String operator++(int);  // 后置++(通过哑元参数区分)
    • 下标运算符([]):需提供 const 和非 const 版本。

      char &String::operator[](int index)const{
          //检查索引是否越界,必须满足在固定的长度内
          if (index < 0 || index >= this->size) {
              static char nullChar = '\0'; // 定义一个静态字符
              return nullChar; // 返回静态字符的引用
          }
          return this->str[index];
      }
       
六、常见问题与解决方案
问题原因解决方法
内存泄漏未释放旧内存在赋值运算符中先 delete[] 再 new
双重释放(double free)浅拷贝导致共享内存实现深拷贝
链式调用失败未返回流或对象引用返回 ostream& 或 String&

 继承

一、继承的核心概念
  1. 作用

    • 减少代码冗余:将多个类的公共属性和方法抽象到父类中,子类通过继承复用代码。

    • 增强扩展性:子类可添加特有属性或覆盖父类方法,实现功能扩展。

  2. 基本语法

    class 子类名 : 访问修饰符 父类名 {
        // 子类特有属性和方法
    };
    • 访问修饰符publicprotectedprivate,决定父类成员在子类中的可见性。

二、用户代码分析
  1. 原始问题

    • 多个英雄类(如 HanzinHouyi)中存在重复的“英雄的属性”,导致代码冗余。

  2. 优化思路

    • 将公共属性提取到基类 Hero 中,特定类型(如射手、法师)进一步抽象为中间类(如 Ranger),最终由具体英雄类继承。

三、继承体系设计示例
  1. 基类:Hero

    #ifndef __HERO_HEAD__
    #define __HERO_HEAD__
    #include <iostream>
    #include <string>
    using namespace std;
    class Hero
    {
    public:
        // 重构函数
        Hero(const string &name = "hero") : name(name) {};
        // 析构函数
        ~Hero()
        {
            cout << "Hero 析构" << endl;
        }
    //英雄特有的名字给一个函数用于访问name
        string get_name() const { return name; }
        void set_name(const string &name) { this->name = name; }
    
        virtual void show() const
        {
            cout << "Name: " << name << endl;
        }
    protected:
        string name;
    };
    
    #endif
  2. 中间类:Ranger(射手)

    #ifndef __RANGER_HEAD__
    #define __RANGER_HEAD__
    #include "hero.h"
    #include <iostream>
    using namespace std;
    class Ranger{   
    public:
    //构造函数
        Ranger(int distance):distance(distance){
            cout << "Ranger 构造函数" <<  endl;
        }
    //获取对应的射程
        int get_distance() const { return distance; }
        void set_distance(int distance) { this->distance = distance; }
    
        void show(){
            cout << "Distance: " << distance <<  endl;
        }
    
        ~Ranger() {
             cout << "Ranger 析构函数" <<  endl;
        }
    
    private:
        int distance;
    };
    
    #endif
  3. 具体类:Drj(狄仁杰) 

    #ifndef DRJ_H
    #define DRJ_H
    #include "hero.h"
    #include "ss.h"
    #include <string>
    #include <iostream>
    
    class Drj : public Ranger,public Hero{  // 仅继承 Ranger(已虚继承 Hero)
    private:
        std::string looks;
    
    public:
        Drj(const std::string &name, int distance, const std::string &looks):Hero(name),Ranger(distance),looks(looks){
            std::cout << "Drj 构造函数" << std::endl;
        }
    
        void show()const{
            Hero::show();  // 调用 Hero 的 show()
            std::cout << "Looks: " << looks << std::endl;
        }
    
        ~Drj(){
            std::cout << "Drj 析构函数" << std::endl;
        }
    };
    
    #endif

    4.Hero_main.cpp:

#include <iostream>
#include "hero.h"
#include "ss.h"
#include "drj.h"

int main() {
    /*若是直接用private:或protected:继承都会出现继承范围越来越小,
    以至于在主函数中都无法使用因此利用public直接继承值或是public函数辅助访问私有或是保护的值*/
    // 创建 Hero 对象
    Hero hero("基础英雄");
    hero.show();
    std::cout << "-----------------" << std::endl;

    // 创建 Ranger 对象攻击范围是100
    Ranger ranger(100);
    ranger.show();
    std::cout << "-----------------" << std::endl;

    // 创建 Drj 对象
    Drj drj("狄仁杰", 150, "英俊");
    drj.show();
    std::cout << "-----------------" << std::endl;

    return 0;
}

 结果显示:

六、继承的优势与注意事项

  1. 优势

    • 代码复用:公共逻辑集中管理,减少重复代码。

    • 层次化设计:通过多级继承实现模块化开发(如 Hero → Ranger → Houyi)。

  2. 注意事项

    • 访问权限:合理使用 publicprotectedprivate 控制成员可见性。

    • 菱形继承问题:避免多继承导致的二义性(可通过虚继承解决)。

    • 父类析构函数:若父类有虚函数,应声明虚析构函数以防止资源泄漏。

关键实践建议

  • 优先使用组合而非继承,避免过度设计。

  • 使用 protected 替代 private 以支持子类扩展。

  • 在复杂继承体系中,合理使用虚函数和多态特性。

四、菱形继承
1. 菱形继承的定义与结构

菱形继承(Diamond Inheritance) 是指一个派生类(如 D)通过多个路径继承自同一个基类(如 A)。具体结构如下:

  • 示例代码结构

    class A { public: int a; };  
    class B : public A {};  
    class C : public A {};  
    class D : public B, public C {}; 
    2. 菱形继承导致的问题
  • 成员重复
    由于 B 和 C 都继承自 AD 会包含两份 A 的成员变量 a(分别通过 B 和 C 继承)。

  • 访问歧义
    当在 D 中直接访问 a 时,编译器无法确定应使用 B::a 还是 C::a,导致编译错误。

示例错误代码

class D : public B, public C {  
public:  
    void function() {  
        a = 200;  // ❌ 错误:reference to 'a' is ambiguous  
    }  
};  

int main() {  
    D object;  
    object.a = 100;  // ❌ 错误:request for member 'a' is ambiguous  
    return 0;  
}  
3. 编译器报错原因
  • 歧义性访问
    D 中存在两个独立的 A 子对象(分别来自 B 和 C),因此 a 在 D 中有两个副本。

  • 错误示例

    Test.cpp:18:17: error: reference to 'a' is ambiguous  
    Test.cpp:25:16: error: request for member 'a' is ambiguous 
4. 解决方法

通过 作用域解析运算符(:: 明确指定访问路径,消除歧义。

修改后代码

class D : public B, public C {  
public:  
    void function() {  
        B::a = 200;  // ✅ 明确指定访问 B 继承的 a  
    }  
};  

int main() {  
    D object;  
    object.C::a = 100;  // ✅ 明确指定访问 C 继承的 a  
    return 0;  
}  
5. 其他解决方法(补充)
  • 虚继承(Virtual Inheritance)
    使用 virtual 关键字继承,确保 D 中只保留一份 A 的成员。

    class B : virtual public A {};  
    class C : virtual public A {};  
    class D : public B, public C {};
    • 优势:无需通过作用域解析符访问,直接使用 a

    • 注意:虚继承会增加对象内存布局的复杂性。

6. 关键结论
问题原因解决方案
成员重复与访问歧义多路径继承同一基类使用 B::a 或 C::a 明确路径
代码冗余多个基类副本虚继承(推荐)
五、访问修饰符 
1、类成员的访问修饰符
修饰符类内部访问子类访问类外访问
public
protected
private

核心规则

  • public:完全开放访问。

  • protected:仅限类内部和子类访问。

  • private:仅限类内部访问。

2、继承方式对成员权限的影响
继承方式基类 public 成员基类 protected 成员基类 private 成员
public保持 public保持 protected不可访问
protected降级为 protected保持 protected不可访问
private降级为 private降级为 private不可访问

核心规则

  • 继承方式决定了基类成员在派生类中的访问权限上限。

  • private 成员始终不可被派生类直接访问。

3、示例代码分析
基类定义
  1. B1 类

    class B1 {
    public:
        int i;      // public
    protected:
        int k;      // protected
    };
  2. B2 类(修正变量名 1 为 l):

    class B2 {
    public:
        int l;      // public
    private:
        int m;      // private
    protected:
        int q;      // protected
    };
  3. B3 类

    class B3 {
    public:
        int p1;     // public
    };
派生类 C 的继承方式
class C : public B2, protected B1, private B3 {
public:
    int c;      // 新增 public 成员
};
成员权限推导
基类成员原始权限继承方式在 C 中的权限是否可外部访问
B2::lpublicpublic 继承public
B2::qprotectedpublic 继承protected
B1::ipublicprotected 继承protected
B1::kprotectedprotected 继承protected
B3::p1publicprivate 继承private
C::c--public

组合

一、组合的核心概念
  • 定义:组合是通过将现有类的对象作为成员嵌入到新类中,构建“整体-部分”关系(即“has-a”或“contains-a”关系)。

  • 典型场景

    • 汽车(Car)包含引擎(Engine)和轮胎(Wheel)。

    • 英雄(Houyi)拥有皮肤(Skin)。

二、组合的实现方式
1. 基本语法
class NewClass {
public:
    // 成员函数
private:
    Class1 obj1;  // 组合:包含 Class1 对象
    Class2 obj2;  // 组合:包含 Class2 对象
};
2. 示例代码分析
class Houyi : public Hero, public Ranger {
public:
    Houyi(const string &name, int distance, int looks, int price, const string &appearance);
    ~Houyi();
    void show() const;

private:
    int looks;
    Skin skin;  // 组合:Skin 对象作为成员
};

// 构造函数初始化列表必须显式初始化成员对象
Houyi::Houyi(...) : Hero(name), Ranger(distance), skin(price, appearance) {
    // 派生类自身逻辑
}
3. 关键规则
  • 成员对象初始化:必须在构造函数的初始化列表中显式调用成员对象的构造函数。

  • 默认构造函数:若未显式初始化,成员对象会调用其默认构造函数(若存在)。

三、构造函数与析构函数的调用顺序
  1. 构造函数调用顺序

    • 按继承顺序调用基类构造函数(Hero → Ranger)。

    • 按成员对象声明顺序调用成员对象的构造函数(Skin)。

    • 最后调用派生类自身的构造函数(Houyi)。

  2. 析构函数调用顺序:与构造函数顺序相反。

    • 先调用派生类的析构函数。

    • 再按成员对象声明逆序调用析构函数(Skin)。

    • 最后按继承逆序调用基类析构函数(Ranger → Hero)。

四、继承与组合的对比
特性继承(is-a)组合(has-a)
关系类型子类是父类的一种特化整体包含部分
耦合度高耦合(父类改动影响子类)低耦合(通过接口交互)
代码复用直接复用父类方法通过成员对象复用功能
灵活性低(编译时绑定)高(运行时动态替换成员对象)
设计原则易违反封装原则符合信息隐藏原则
五、组合的优缺点
优点
  1. 低耦合:成员对象通过接口交互,隐藏实现细节。

  2. 动态扩展:可在运行时替换成员对象(例如更换引擎)。

  3. 强封装性:成员对象的内部细节对整体类不可见。

缺点
  1. 对象数量增多:可能导致内存占用增加。

  2. 接口设计复杂:需设计清晰的接口协调多个成员对象。

六、组合的应用示例

任务:为“狄仁杰”类添加 Skin 成员并显示信息

class DiRenJie : public Hero {
public:
    DiRenJie(const string &name, int skillLevel, const Skin &skin) 
        : Hero(name), skin(skin), skillLevel(skillLevel) {}

    void showInfo() const {
        cout << "Name: " << getName() << endl;
        cout << "Skill Level: " << skillLevel << endl;
        cout << "Skin: " << skin.getAppearance() << " (Price: " << skin.getPrice() << ")" << endl;
    }

private:
    int skillLevel;
    Skin skin;  // 组合:包含 Skin 对象
};

  • 这是本人的学习笔记不是获利的工具,小作者会一直写下去,希望大家能多多监督
  • 文章会每攒够两篇进行更新发布(受平台原因,也是希望能让更多的人看见)
  • 感谢各位的阅读希望我的文章会对诸君有所帮助

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

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

相关文章

AlarmClock4.8.4(官方版)桌面时钟工具软件下载安装教程

1.软件名称&#xff1a;AlarmClock 2.软件版本&#xff1a;4.8.4 3.软件大小&#xff1a;187 MB 4.安装环境&#xff1a;win7/win10/win11(64位) 5.下载地址&#xff1a; https://www.kdocs.cn/l/cdZMwizD2ZL1?RL1MvMTM%3D 提示&#xff1a;先转存后下载&#xff0c;防止资…

白鲸开源WhaleStudio与崖山数据库管理系统YashanDB完成产品兼容互认证

近日&#xff0c;北京白鲸开源科技有限公司与深圳计算科学研究院联合宣布&#xff0c;双方已完成产品兼容互认证。此次认证涉及深圳计算科学研究院自主研发的崖山数据库管理系统YashanDB V23和北京白鲸开源科技有限公司的核心产品WhaleStudio V2.6。经过严格的测试与验证&#…

【金仓数据库征文】- 金融HTAP实战:KingbaseES实时风控与毫秒级分析一体化架构

文章目录 引言&#xff1a;金融数字化转型的HTAP引擎革命一、HTAP架构设计与资源隔离策略1.1 混合负载物理隔离架构1.1.1 行列存储分区策略1.1.2 四级资源隔离机制 二、实时流处理与增量同步优化2.1 分钟级新鲜度保障2.1.1 WAL日志增量同步2.1.2 流计算优化 2.2 物化视图实时刷…

Windows与CasaOS跨平台文件同步:SyncThing本地部署与同步配置流程

文章目录 前言1. 添加镜像源2. 应用安装测试3. 安装syncthing3.1 更新应用中心3.2 SyncThing安装与配置3.3 Syncthing使用演示 4. 安装内网穿透工具5. 配置公网地址6. 配置固定公网地址 推荐 ​ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽…

59、微服务保姆教程(二)Nacos--- 微服务 注册中心 + 配置中心

Nacos— 微服务 注册中心 + 配置中心 一.什么是Nacos? Nacos是阿里的一个开源产品,是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。 Nacos核心定位是“一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台”,也就是我们的注册中心和配…

第一部分:git基本操作

目录 1、git初识 1.1、存在的问题 1.2、版本控制器 1.3、git安装 1.3.1、CentOS平台 1.3.2、ubuntu平台 2、git基本操作 2.1、创建仓库 2.2、配置git 3、工作区、暂存区、版本库 4、基本操作 4.1、场景一 4.2、场景二 4.3、修改文件 5、版本回退 6、撤销修改 …

《一文读懂Transformers库:开启自然语言处理新世界的大门》

《一文读懂Transformers库:开启自然语言处理新世界的大门》 GitHub - huggingface/transformers: 🤗 Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX. HF-Mirror Hello! Transformers快速入门 pip install transformers -i https:/…

2025年GPLT团体程序设计天梯赛L1-L2

目录 1.珍惜生命 2.偷感好重 3.高温补贴 4.零头就抹了吧 5.这是字符串题 6.这不是字符串题 7.大幂数​编辑 8.现代战争​编辑 9.算式拆解 10.三点共线 11.胖达的山头 12.被n整除的n位数 1.珍惜生命 【解析】直接输出即可 #include<bits/stdc.h> using namespace…

【每天一个知识点】IPv4(互联网协议版本4)和IPv6(互联网协议版本6)

IPv4&#xff08;互联网协议版本4&#xff09;和IPv6&#xff08;互联网协议版本6&#xff09;是用于在互联网上标识和定位设备的两种主要协议。它们的主要区别在于地址空间、结构、以及一些附加功能。以下是两者的对比&#xff1a; 1. 地址长度 IPv4: 地址长度为32位&#xf…

金仓数据库征文-政务领域国产化数据库更替:金仓 KingbaseES 应用实践

目录 一.金仓数据库介绍 二.政务领域数据库替换的时代需求​ 三.金仓数据库 KingbaseES 在政务领域的替换优势​ 1.强大的兼容性与迁移能力​ 2.高安全性与稳定性保障​ 3.良好的国产化适配性​ 四.金仓数据库 KingbaseES 在政务领域的典型应用实践​ 1.电子政务办公系…

Android Studio开发中Application和Activity生命周期详解

文章目录 Application生命周期Application生命周期概述Application关键回调方法onCreate()onConfigurationChanged()onLowMemory()onTrimMemory()onTerminate() Application生命周期管理最佳实践 Activity生命周期Activity生命周期概述Activity生命周期回调方法onCreate()onSta…

【金仓数据库征文】金仓数据库:开启未来技术脑洞,探索数据库无限可能

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 目录 引言&#xff1a;数据库进化的下一站 —— 未来科技的无限可能金仓数据库简介&#xff1a;国…

微信小程序根据图片生成背景颜色有效果图

效果图 取得是图片中间10个像素算出背景颜色 .wxml <canvas type"2d" id"imageCanvas" style"--w: {{w}}px;--h: {{h}}px;" /> <view style"background: {{backgroundColor}};"><image bind:tap"updateIndex&qu…

Redis ⑥-string | hash | list

string类型基本介绍 Redis 中的字符串&#xff0c;是直接按照二进制的方式进行存储的。也就是说&#xff0c;在存取的过程中&#xff0c;是不会做任何编码转换的。存的是啥&#xff0c;取的时候就是啥。 Redis 的这个机制&#xff0c;就使得 Redis 非常适合用来存储各种各样的…

深入理解C语言函数之模拟实现strcpy()strcat()

文章目录 前言一、strcpy的模拟实现二、strcat的模拟实现总结 前言 前面我们用三种方法模拟实现了一下strlen&#xff0c;所以这篇文章模拟实现以下strcpy&#xff08;&#xff09;strcat&#xff08;&#xff09; 一、strcpy的模拟实现 首先我们去官网找到strcpy的用法和原…

大数据组件学习之--Kafka 安装搭建

一、前置环境 在搭建kafka之前&#xff0c;请确认自己的hadoop、zookeeper是否搭建完成且可正常运行 二、下载并上传安装包&#xff08;链接为百度网盘&#xff09; kafka安装包 tar -zxvf /opt/software/kafka_2.12-2.4.1.tgz -C /opt/module/ 进入解压后的目录更改文件名…

BIOS主板(非UEFI)安装fedora42的方法

BIOS主板(非UEFI)安装fedora42的方法 现实困难&#xff1a;将Fedora-Workstation-Live-42-1.1.x86_64.iso写入U盘制作成可启动U盘启动fedora42&#xff0c;按照向导将fedora42安装到真机的sda7分区中得到报错如下内容&#xff1a; /boot/efi 必需的 /boot/efi必须位于格式化为e…

[吾爱出品] 【键鼠自动化工具】支持识别窗口、识图、发送文本、按键组合等

键鼠自动化工具 链接&#xff1a;https://pan.xunlei.com/s/VOOhDZkj-E0mdDZCvo3jp6s4A1?pwdfufb# 1、增加的找图点击功能&#xff08;不算增加&#xff0c;只能算缝补&#xff09;&#xff0c;各种的不完善&#xff0c;但是能运行。 2、因为受限于原程序的界面&#xff0c;…

图解YOLO(You Only Look Once)目标检测(v1-v5)

1. YOLO系列整体介绍 YOLO属于深度学习经典检测方法中的单阶段&#xff08;one - stage&#xff09;类型&#xff0c;与两阶段&#xff08;two - stage&#xff0c;如Faster - rcnn、Mask - Rcnn系列&#xff09;方法相对。 不同模型性能 单阶段方法的最核心优势是速度非常快…

基于AI应用创业IDEA:使用百度搜索开放平台的MCP广场智能推荐MCPServices服务

基于AI应用创业IDEA&#xff1a;使用百度搜索开放平台的MCP广场智能推荐MCPServices服务 在当今快速发展的技术时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为推动各行各业创新的关键力量。特别是在创业领域&#xff0c;AI技术不仅能够帮助提升产品性能&#xf…