【c++】cpp类的继承

news2025/2/23 11:41:03

目录

(1)继承概念与语法

(2)派生类的访问控制

(3)继承中的构造和析构

1.类型兼容性原则

2.继承中的构造析构调用原则

3.继承与组合混搭下构造和析构调用原则

(4)同名成员(函数)的继承

(5)static成员的继承

(6)多继承与虚继承

1.多继承的语法

2.多继承的二义性

3.用虚继承解决二义性

4.虚继承的实现原理

5.虚继承解决二义性的作用也有限


(1)继承概念与语法

类之间的关系:has-A,uses-A 和 is-A

  • has-A   包含关系,⽤以描述⼀个类由多个“部件类”构成。实现has-A关系⽤类成员表示, 即⼀个类中的数据成员是另⼀种已经定义的类。
  • uses-A  ⼀个类部分地使⽤另⼀个类。通过类之间成员函数的相互联系,定义友员或对象参 数传递实现。
  • is-A   机制称为“继承”。关系具有传递性,不具有对称性。

继承是类之间定义的一种重要关系。一个B类继承A类,或称从类A派生类B。类A称为基类(父类),类B称为派生类(子类)。

继承的重要作用就在于随着业务的不断变化,提出了新的业务需求,需要开发新的类,但又仍需要父类的某些功能,因此有了继承这个概念,子类继承自父类,可以继续使用父类的某些属性或者功能,同时又能有专属自己的功能。

类继承的语法

// 单继承
class 子类名: 访问控制关键字 父类名
{
    数据成员和成员函数声明
};

// 多继承
class 子类名: 访问控制关键字 父类名1, 访问控制关键字 父类名2, ...
{
    数据成员和成员函数声明
};

访问控制关键字表示子类对父类的继承方式:

public    公有继承
private   私有继承
protected 保护继承

继承重要说明

  • ⼦类拥有⽗类的所有成员变量和成员函数
  • ⼦类可以拥有⽗类没有的⽅法和属性
  • ⼦类就是⼀种特殊的⽗类
  • ⼦类对象可以当作⽗类对象使用(比如函数参数要求传递父类对象,传递子类对象也可)

如何访问继承的成员或者函数:假设a是父类Parent的成员,child为Child的实例化对象,则可以通过这两种方式访问:

  • child.Parent::a
  • child.a

关于继承方式:采用不同的继承方式会影响从父类手中接盘资产的访问属性,这个将在下一节讲解,这里以public继承为例,子类将原封不动地接盘父类的全部资产,且资产属性不变。

示例代码

#include <iostream>

class Parent
{
public:
    int b;
public:
    void print()
    {
        a = 0;
        b = 0;
        std::cout << "a = " << a << std::endl;
        std::cout << "b = " << b << std::endl;
    }

private:
    int a;
protected:
};

// 子类继承父类
// class Child : private Parent
// class Child : protected Parent
class Child : public Parent
{
public:
private:
    int c;
protected:
};

int main()
{
    Child c1;
    c1.print();
    std::cout << "c1.b = " << c1.b << std::endl;

    // 也可以这样访问继承的成员
    std::cout << "c1.b = " << c1.Parent::b << std::endl; 

    return 0;
}

运行结果

a = 0
b = 0
c1.b = 0
c1.b = 0

(2)派生类的访问控制

1.理解成员属性

  • public: 修饰的成员变量⽅法 ,在类的内部和类的外部都能使⽤
  • protected: 修饰的成员变量⽅法,在父类和子类的内部可⽤ ,在外部不能被使⽤
  • private: 修饰的成员变量⽅法,只能在类的内部使⽤,不能在类的外部,不可继承

2.不同的继承方式会改变继承成员的访问属性

派⽣类继承了基类的全部成员变量和成员方法(除了构造和析构之外的成员方法),但是这些成 员的访问属性,在派生过程中是可以调整的。

  • public继承:⽗类成员在⼦类中保持原有访问级别
  • private继承:⽗类成员在⼦类中变为private成员
  • protected继承:
    • 父类中public成员会变成protected
    • ⽗类中protected成员仍然为protected
    • ⽗类中private成员仍然为private

注意:private成员在⼦类中依然存在,但是却⽆法访问到。不论种⽅式继承基类,派⽣类都不能直接 使⽤基类的私有成员。

项目开发中 一般情况下 是 class B : public A。

示例代码

#include <iostream>
#include <string>

class Parent
{
public:
    Parent()
    {
        name = "parent";
        password = 123;
        emotion_friend = 0;
    }
public:
    std::string name;    //老爹的名字
protected:
    int password;        //老爹的银行密码
private:
    int emotion_friend;   //老爹的情人 // 私有的无论怎样继承,儿子都没法访问
};

// 公有继承
class Child1 : public Parent
{
public:
    void useVar()
    {
        std::cout << name << std::endl;  // ok
        std::cout << password << std::endl;  // ok
        // std::cout << emotion_friend << std::endl;  // error
        return;
    }
};

// 私有继承
class Child2 : private Parent
{
public:
    void useVar()
    {
        std::cout << name << std::endl;  // ok
        std::cout << password << std::endl;  // ok
        // std::cout << emotion_friend << std::endl;  // error
        return;
    }
};

// 保护继承
class Child3 : protected Parent
{
public:
    void useVar()
    {
        std::cout << name << std::endl;  // ok
        std::cout << password << std::endl;  // ok
        // std::cout << emotion_friend << std::endl;  // error
        return;
    }
};


int main()
{
    // 1.公有继承
    std::cout << "----------------" << std::endl;
    Child1 c1;
    c1.name = "child1"; // ok
    // c1.password = 456; // err,因为protected不能外部访问
    // c1.emotion_friend = 1; // err,因为private不能外部访问

    c1.useVar();

    // 2.私有继承
    std::cout << "----------------" << std::endl;
    Child2 c2;
    // c2.name = "child1"; // err,因为private不能外部访问
    // c2.password = 456; // err,因为private不能外部访问
    // c1.emotion_friend = 1; // err,因为private不能外部访问

    c2.useVar();

    // 3.保护继承
    std::cout << "----------------" << std::endl;
    Child3 c3;
    // c3.name = "child1"; // err,因为protected不能外部访问
    // c3.password = 456; // err,因为protected不能外部访问
    // c3.emotion_friend = 1; // err,因为private不能外部访问
    
    c3.useVar();
    
    return 0;
}

运行结果

----------------
child1
123
----------------
parent
123
----------------
parent
123

(3)继承中的构造和析构

1.类型兼容性原则

类型兼容规则是指在需要基类对象的任何地⽅,都可以使⽤公有派⽣类的对象来替代。通过公有 继承,派⽣类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具 备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。

类型兼容规则中所指的替代包括以下情况:

  • 子类对象可以当作父类对象使用
  • 子类对象可以直接赋值给父类对象
  • 子类对象可以直接初始化父类对象
  • 父类指针可以直接指向子类对象
  • 父类引⽤可以直接引用子类对象

在替代之后,派生类对象就可以作为基类的对象使⽤,但是只能使用从基类继承的成员。

总结:子类就是特殊的⽗类 (base *p = &child;)

#include <iostream>
#include <string>

class Parent
{
public:
    void printP()
    {
        std::cout << "I'm Parent" << std::endl;
    }
public:
    Parent()
    {
        std::cout << "Parent Normal Generate Func" << std::endl;
    }
    Parent(Parent &obj)
    {
        std::cout << "Parent Copy Generate Func" << std::endl;
    }
private:
    int a;
};

class Child : public Parent
{
public:
    void printC()
    {
        std::cout << "I'm Child" << std::endl;
    }
protected:
private:
    int c;
};

void PrintParent(Parent *p)
{
    p->printP();
}
void PrintParent(Parent &base)
{
    base.printP();
}

int main()
{
    Parent parent1;   // Parent Normal Generate Func
    parent1.printP(); // I'm Parent

    // 使用继承来的成员
    Child child1;    // Parent Normal Generate Func
    child1.printC(); // I'm Child
    child1.printP(); // I'm Parent

    //父类指针指向子类对象
    Parent *p = NULL;
    p = &child1;
    p->printP(); // I'm Parent

    //指针做函数参数
    PrintParent(&parent1); //I'm Parent
    PrintParent(p);   //I'm Parent

    //引用做函数
    PrintParent(child1); //I'm Parent
    PrintParent(parent1); //I'm Parent

    //子类对象 初始化 父类对象
    Parent parent2 = child1; // Parent Copy Generate Func
    parent2.printP();    //I'm Parent

    return 0;
}

2.继承中的构造析构调用原则

问题:如何初始化父类成员?父类与子类的构造函数有什么关系

  • 在子类对象构造时,需要调用父类构造函数对其继承得来的成员进⾏初始化
    • 子类对象在创建时会首先调⽤父类的构造函数
    • 父类构造函数执行结束后,执行子类的构造函数
    • 当父类的构造函数有参数时,需要在子类的初始化列表中显示调⽤
  • 在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理
    • 析构函数调⽤的先后顺序与构造函数相反

示例代码

#include <iostream>

class Parent
{
public:
    Parent(int a = 0, int b = 0)
    {
        this->a = a;
        this->b = b;
        std::cout << "Parent Normal Generate Func" << std::endl;
    }
    Parent(const Parent &obj)
    {
        std::cout << "Parent Copy Generate Func" << std::endl;
    }
    ~Parent()
    {
        std::cout << "Parent Destroyed Func" << std::endl;
    }
private:
    int a;
    int b;
};

class Child : public Parent
{
public:
    Child(int a, int b, int c):Parent(a, b)
    {
        this->c = c;
        std::cout << "Child Normal Generate Func" << std::endl;
    }
    ~Child()
    {
        std::cout << "Child Destroyed Func" << std::endl;
    }
protected:
private:
    int c;
};



int main()
{
    Child c1(1, 2, 5);

    return 0;
}

运行结果

Parent Normal Generate Func
Child Normal Generate Func
Child Destroyed Func
Parent Destroyed Func

3.继承与组合混搭下构造和析构调用原则

构造顺序:先祖宗类构造 → 父类构造 → 成员变量构造 → 再自己构造

析构顺序:先自己析构 → 再成员变量析构 → 再父类析构 → 再祖宗类析构

示例代码

#include <iostream>


// 祖宗类
class GrandParent
{
public:
    GrandParent(int a, int b)
    {
        this->a = a;
        this->b = b;
        std::cout << "GrandParent Normal Generate Func: " 
                  << a << "," << b << std::endl;
    }
    ~GrandParent()
    {
        std::cout << "GrandParent Destroyed Func" << std::endl;
    }
private:
    int a;
    int b;
};

// 父类,继承于祖宗类
class Parent: public GrandParent
{
public:
    Parent(char *p): GrandParent(1, 2)
    {
        this->p = p;
        std::cout << "Parent Normal Generate Func:  " << p << std::endl;
    }
    ~Parent()
    {
        std::cout << "Parent Destroyed Func" << std::endl;
    }
private:
    char *p;
};

// 子类,继承于父类
class Child : public Parent
{
public:
    Child(char *p):Parent(p), gp1(3, 4), gp2(5, 6)
    {
        this->cp = p;
        std::cout << "Child Normal Generate Func:   " << p << std::endl;
    }
    ~Child()
    {
        std::cout << "Child Destroyed Func" << std::endl;
    }
public:
protected:
    char *cp;
    GrandParent gp1;
    GrandParent gp2;
};



int main()
{
    char data[] = "test";
    std::cout << "-----------Generate-----------" << std::endl;
    Child c1(data);

    std::cout << "-----------Destroy-----------" << std::endl;

    return 0;
}

运行结果

-----------Generate-----------
GrandParent Normal Generate Func: 1,2
Parent Normal Generate Func:  test
GrandParent Normal Generate Func: 3,4
GrandParent Normal Generate Func: 5,6
Child Normal Generate Func:   test
-----------Destroy-----------
Child Destroyed Func
GrandParent Destroyed Func
GrandParent Destroyed Func
Parent Destroyed Func
GrandParent Destroyed Func

(4)同名成员(函数)的继承

当子类成员变量与父类成员变量同名时

  • 子类依然从⽗类继承同名成员
  • 在⼦类中通过作⽤域分辨符 :: 进⾏同名成员区分。在⼦类外部⽤ childObj.Parent::name 和 childObj.Child::name,在⼦类内部⽤Parent::name和Child::name。
  • 同名成员变量和成员函数通过作⽤域分辨符进⾏区分。调⽤name默认是childObj.Child::name和 Child::name。
  • 同名成员存储在内存中的不同位置

示例代码

#include <iostream>

class Parent
{
public:
    Parent(int a = 0, int b = 0)
    {
        this->a = a;
        this->b = b;
    }
public:
    void print(){ std::cout << "print parent" << std::endl;}
    void get(){ std::cout << "a=" << a << ",b=" << b << std::endl;}
public:
    int a;
    int b;
};

class Child : public Parent
{
public:
    Child(int a=0, int b=0, int c=0):Parent(a, b)
    {
        this->b = b;
        this->c = c;
    }
public:
    void print(){ std::cout << "print child" << std::endl;}
    void get(){ std::cout << "a=" << a << ",b=" << b << ",c=" << c << std::endl;}
public:
    int b;
    int c;

};



int main()
{
    Child c1(1, 2, 3);

    // 1.同名变量
    std::cout << c1.b << std::endl;         // 2
    std::cout << c1.Child::b << std::endl;  // 2
    std::cout << c1.Parent::b << std::endl; // 2

    //修改父类的b
    c1.Parent::b = 100;
    std::cout << c1.Parent::b << std::endl; // 100
    std::cout << c1.Child::b << std::endl;  // 2
    std::cout << c1.b << std::endl;         // 2

    // 2.同名函数
    c1.print();         // print child
    c1.Child::print();  // print child //默认情况
    c1.Parent::print(); // print parent

    c1.get();         // a=1,b=2,c=3
    c1.Child::get();  // a=1,b=2,c=3
    c1.Parent::get(); // a=1,b=100

    return 0;
}

(5)static成员的继承

  • 基类定义的静态成员,将被所有派生类共享
  • 根据静态成员自身的访问特性和派生类的继承⽅式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)
  • 在派生类的内部访问静态成员,直接变量名即可:
  • 在派生类中的外部访问静态成员,⽤以下形式:
    • 类名 :: 成员
    • 对象名 . 成员

示例代码

#include <iostream>


class Parent
{
public:
    Parent()
    {
        std::cout << "Parent generate func" << std::endl;
    }
public:
    void printa()
    {
        std::cout << "class Parent call: static a=" << a << std::endl;
    }
public:
    static int a;
    int b;
protected:
private:
};

// 静态变量的初始化
int Parent::a = 100; //这句话 不是简单的变量赋值
// 更重要的是 要告诉C++编译器 你要给我分配内存
// 我在继承类中 用到了a 不然会报错..

class Child : private Parent
{
public:
    Child()
    {
        std::cout << "Child generate func" << std::endl;
    }
public:
    void printa()
    {
        std::cout << "class Child call: static a=" << a << std::endl;
    }
public:
    int b;
    int c;
protected:
private:
};

// 1 static关键字 遵守  派生类的访问控制规则
// 2 不是简单的变量赋值 更重要的是 要告诉C++编译器
// 你要给我分配内存 ,我再继承类中 用到了a 不然会报错..


void objplay()
{
    Parent parent1;         
    parent1.printa();  

    Child child1;        
    child1.printa();
    // child1.a = 200; //非法,因为是私有继承,只能在类的内部共享

    std::cout << Parent::a << std::endl;  // 访问同一个静态成员
    std::cout << parent1.a << std::endl;  // 访问同一个静态成员
    // std::cout << child1.a << std::endl;  // 将会error,因为私有继承
}

int main()
{
    objplay();

    return 0;
}

运行结果

Parent generate func
class Parent call: static a=100
Parent generate func
Child generate func
class Child call: static a=100
100
100

(6)多继承与虚继承

1.多继承的语法

多继承的派生类构造和访问
  • 多个基类的派生类构造函数可以用初始化列表调用基类构造函数初始化数据成员
  • 执⾏顺序与单继承构造函数情况类似。多个直接基类构造函数执⾏顺序取决于定义派⽣类时 指定的各个继承基类的顺序。
  • ⼀个派⽣类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现⼆义性。如果不 同的基类有同名成员,派⽣类对象访问时应该加以识别。
示例代码
#include <iostream>

class Base1
{
public:
    Base1(int b1)
    {
        std::cout << "Base1 generate func" << std::endl;
        this->b1 = b1;
    }
    ~Base1()
    {
        std::cout << "Base1 destroy func" << std::endl;
    }
    void printB1()
    {
        std::cout << "b1:" << b1 << std::endl;;
    }
protected:
private:
    int b1;
};

class Base2
{
public:
    Base2(int b2)
    {
        std::cout << "Base2 generate func" << std::endl;
        this->b2 = b2;
    }
    ~Base2()
    {
        std::cout << "Base2 destroy func" << std::endl;
    }
    void printB2()
    {
        std::cout << "b2:" << b2 << std::endl;;
    }
protected:
private:
    int b2;
};

class Child : public Base1, public Base2
{
public:
    Child(int b1, int b2, int c) : Base2(b2), Base1(b1)
    {
        std::cout << "Child generate func" << std::endl;
        this->c = c;
    }
    ~Child()
    {
        std::cout << "Child destroy func" << std::endl;
    }
    void printC()
    {
        std::cout << "c:" << c << std::endl;;
    }
protected:
private:
    int c;
};

int main()
{
    Child c1(1, 2, 3);

    c1.printC();
    c1.printB1();
    c1.printB2();

    return 0;
}

运行结果

Base1 generate func
Base2 generate func
Child generate func
c:3
b1:1
b2:2
Child destroy func
Base2 destroy func
Base1 destroy func

2.多继承的二义性

示例代码

#include <iostream>

class B
{
public:
    int b;
};

class B1 : public B
{
public:
    int b1;
};


class B2 : public B
{
public:
    int b2;
};

class C : public B1, public B2
{
public:
    int c;
};

int main()
{

    C c1;
    c1.b1 = 100;
    c1.b2 = 200;
    c1.c = 300;
    
    // c1.b = 500; //这句会报错,因为二义性,
    //  到底是B1的的b,还是B2的b分不清

    return 0;
}

3.用虚继承解决二义性

  • 如果⼀个派生类从多个基类派⽣,⽽这些基类⼜有⼀个共同的基类,则在对该基类中声明的 名字进⾏访问时,可能产⽣⼆义性
  • 如果在多条继承路径上有⼀个公共的基类,那么在继承路径的某处汇合点,这个公共基类就 会在派生类的对象中产生多个基类子对象
  • 要 使这个公共基类在派生类中只产生⼀个子对象,必须对这个基类声明为虚继承,使这个基 类成为虚基类
  • 虚继承声明使用关键字:virtual

像下面这样

示例代码

#include <iostream>

class B
{
public:
    int b;
};

class B1 : virtual public B
{
public:
    int b1;
};


class B2 : virtual public B
{
public:
    int b2;
};

class C : public B1, public B2
{
public:
    int c;
};

int main()
{

    C c1;
    c1.b1 = 100;
    c1.b2 = 200;
    c1.c = 300;

    c1.b = 500; //因为virtual继承,这里将不会再报错
    std::cout << c1.B1::b << std::endl;  // 500

    c1.B1::b = 600;
    std::cout << c1.b << std::endl; // 600
    
    c1.B2::b = 700;
    std::cout << c1.b << std::endl; // 700

    c1.B::b = 1000;
    std::cout << c1.b << std::endl; // 1000

    return 0;
}

4.虚继承的实现原理

如果继承的多个基类有⼀个共同的基类,则⽤虚继承时只会把⽼祖宗的构造函数只只执⾏⼀次, 而不是执行多次使得产生⼆义性。

示例代码

#include <iostream>

class B
{
public:
    B()
    {
        std::cout << "B copy generate func" << std::endl;
    }
    int b;
};

class B1 : virtual public B
{
public:
    int b1;
};


class B2 : virtual public B
{
public:
    int b2;
};

class B3 : virtual public B
{
public:
    int b3;
};

class B4 : virtual public B
{
public:
    int b4;
};

class C1 : public B1, public B2
{
public:
    int c1;
};

class C2 : public B3, public B4
{
public:
    int c2;
};

int main()
{
    //加上virtual以后 , C++编译器会在给变量偷偷增加属性
    std::cout << "----------------------" << std::endl;
    std::cout << sizeof(B) << std::endl;
    std::cout << sizeof(B1) << std::endl;
    std::cout << sizeof(B2) << std::endl;
    std::cout << sizeof(B3) << std::endl;
    std::cout << sizeof(B4) << std::endl;

    std::cout << "----------------------" << std::endl;
    C1 c1;
    c1.b1 = 100;
    c1.b2 = 200;

    std::cout << "----------------------" << std::endl;
    C2 c2;
    c2.b3 = 500;
    c2.b4 = 600;
    c2.b = 700;

    c2.B3::b3 = 1000;
    c2.B::b = 99;

    return 0;
}

运行结果

----------------------
4
16
16
16
16
----------------------
B copy generate func
----------------------
B copy generate func

5.虚继承解决二义性的作用也有限

对于下图右边这种多继承,虚继承也无法解决⼆义性。

只能通过作用域符号来明确,c.B1::k,c.B2::k


end

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

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

相关文章

OI Wiki—递归 分治

//新生训练&#xff0c;搬运整理 递归 定义 递归&#xff08;英语&#xff1a;Recursion&#xff09;&#xff0c;在数学和计算机科学中是指在函数的定义中使用函数自身的方法&#xff0c;在计算机科学中还额外指一种通过重复将问题分解为同类的子问题而解决问题的方法。 引入…

Python语言零基础入门——模块

目录 一、模块的导入与使用 1.模块的导入 2.模块的使用 二、包的使用 1.包 2.包的使用 三、常见的标准库 1.random的运用举例 2.random小游戏 &#xff08;1&#xff09;石头剪刀布 &#xff08;2&#xff09;猜大小 3.re 4.time库的使用 5.turtle库的使用 6.so…

Zapier 与生成式 AI 的自动化(一)

原文&#xff1a;zh.annas-archive.org/md5/057fe0c351c5365f1188d1f44806abda 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 当组织处理手动和重复性任务时&#xff0c;生产力会遇到重大问题。Zapier 处于无代码运动的前沿&#xff0c;提供了一种先进的工具&a…

【C++】详解string类

目录 简介 框架 构造 全缺省构造函数 ​编辑 传对象构造函数 拷贝构造 析构函数 容量 size() capacity&#xff08;&#xff09; empty() clear() reserve() ​编辑 resize() 遍历 检引用符号"[ ]"的重载 迭代器 begin() end() rbegin() rend(…

【竞技宝】欧冠:拜仁2比2战平皇马,金玟哉状态低迷

拜仁在欧冠半决赛首回合较量中坐镇主场跟皇马相遇,这场比赛踢得非常激烈好看。拜仁并没有在主场苟着踢,而是跟皇马打对攻,让球迷大呼过瘾。最终,拜仁与皇马激战90分钟后,以2比2比分战平。对于这样的比赛结果,大部分拜仁球迷都觉得不服气。因为,他们认为自家中卫金玟哉太差,如果…

3D建模在游戏行业的演变和影响

多年来&#xff0c;游戏行业经历了显着的转变&#xff0c;这主要是由技术进步推动的。 深刻影响现代游戏的关键创新之一是 3D 建模领域。 从像素化精灵时代到我们今天探索的错综复杂的游戏世界&#xff0c;3D 建模已成为游戏开发不可或缺的基石。 本文讨论 3D 建模在游戏行业中…

智能健康管理子卡(ChMC/IPMC)模块,支持IPMI2.0标准通信协议,0Kbps可配置,可通过IPMI命令控制其他刀片开关电,具备故障上报、开机自检

是一款BMC子卡&#xff0c;该子卡输出1路千兆网络接口与千兆交换芯片相连,对外输出1路百兆调试网络接口&#xff0c;对外输出2路8路&#xff08;可选&#xff09;IPMB&#xff08;I2C&#xff09;接口并做隔离处理&#xff08;I2C BUFFER&#xff09;&#xff0c;支持IPMI2.0标…

【代码随想录——链表】

1.链表 什么是链表&#xff0c;链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个节点的指针域指向null&#xff08;空指针的意思&#…

rust疑难杂症

rust疑难杂症解决 边碰到边记录&#xff0c;后续可能会逐步增加&#xff0c;备查 cargo build时碰到 Blocking waiting for file lock on package cache 原因是Cargo 无法获取对包缓存的文件锁&#xff0c; 有时vscode中项目比较多&#xff0c;如果其中某些库应用有问题&…

脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)

0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备管理中心、消费管理子系统、订餐管理子系统、水控管…

Kafka介绍、安装以及操作

Kafka消息中间件 1.Kafka介绍 1.1 What is Kafka&#xff1f; 官网&#xff1a; https://kafka.apache.org/超过 80% 的财富 100 强公司信任并使用 Kafka &#xff1b;Apache Kafka 是一个开源分布式事件流平台&#xff0c;被数千家公司用于高性能数据管道、流分析、数据集成…

CentOS7安装MySQL8.3(最新版)踩坑教程

安装环境说明 项值系统版本CentOS7 &#xff08;具体是7.9&#xff0c;其他7系列版本均可&#xff09;位数X86_64&#xff0c;64位操作系统MySQL版本mysql-8.3.0-1.el7.x86_64.rpm-bundle.tar 实际操作 官网下载安装包 具体操作不记录&#xff0c;相关教程很多。 mkdir /o…

Mysql-黑马

Mysql-黑马 编写规范&#xff1a;## 一级1. 二级三级 1.Mysql概述 数据库概念mysql数据仓库 cmd启动和停止 net start mysql180 net stop mysql180备注&#xff1a;其中的mysql180是服务名 客户端连接 远程连接数据仓库 -h 主机号 -P端口号 mysql [-h 127.0.0.1] [-P 33…

YOLOv5改进之bifpn

目录 一、原理 二、代码 三、在YOLOv5中的应用 一、原理 论文链接:

Android4.4真机移植过程笔记(二)

5、盘符挂载 先定义overlay机制路径&#xff0c;后面storage_list.xml要用到&#xff1a; 在路径&#xff1a; rk3188_android4.4.1/device/rockchip/OK1000/overlay/frameworks/base/core/res/res/xml/定义好&#xff0c;注意名字要和emmc的代码片段&#xff08;往下面看&am…

大数据信用花了,一般多久能正常?

在当今数字化时代&#xff0c;大数据技术被广泛应用于各个领域&#xff0c;包括金融、电商、社交等。然而&#xff0c;随着大数据技术的普及&#xff0c;个人信用问题也日益凸显&#xff0c;其中“大数据信用花”现象尤为引人关注。那么&#xff0c;大数据信用花究竟是什么?一…

(四)小程序学习笔记——自定义组件

1、组件注册——usingComponents &#xff08;1&#xff09;全局注册&#xff1a;在app.json文件中配置 usingComponents进行注册&#xff0c;注册后可以在任意页面使用。 &#xff08;2&#xff09;局部注册&#xff0c;在页面的json文件中配置suingComponents进行注册&#…

2023 广东省大学生程序设计竞赛(部分题解)

目录 A - Programming Contest B - Base Station Construction C - Trading D - New Houses E - New but Nostalgic Problem I - Path Planning K - Peg Solitaire A - Programming Contest 签到题&#xff1a;直接模拟 直接按照题目意思模拟即可&#xff0c;为了好去…

labview强制转换的一个坑

32位整形强制转换成枚举的结果如何&#xff1f; 你以为的结果是 实际上的结果是 仔细看&#xff0c;枚举的数据类型是U16&#xff0c;"1"的数据类型是U32&#xff0c;所以转换产生了不可预期的结果。所以使用强制转换时一定要保证两个数据类型一致&#xff0c;否则…

04 - 步骤 JSON input

简介 Kettle 的 JSON Input 步骤是用于从 JSON 格式的数据源中读取数据的步骤。它允许用户指定 JSON 格式的输入数据&#xff0c;然后将其转换成 Kettle 中的行流数据&#xff0c;以供后续的数据处理、转换和加载操作使用。 使用 场景 1、拖拽到面板 2、指定JSON input 为 K…