当前位置: 首页 > news >正文

什么是私有继承

私有,公有,针对类而言;

私有( private )的成员,自己的,只能在自己内部( 类的定义体内部 )访问,外部( 类的定义体外部 )不能访问/调用;

公有( 或者说公开,public )的成员,对外开放的,可以在自己外面( 类的定义体外部 )被访问到,即,可调用/访问到;

1. 什么是私有继承?其目的与好处是什么?

私有继承是 C++ 中的一种继承方式,它使得基类的公有和保护成员,在派生类中,变为派生类的私有成员。也就是说,派生类的实例对象不能直接访问基类的公有成员,但可以在派生类的定义体内部访问基类的公有成员和保护成员。
“私有继承”,类似于一个私生子,私生子可以有父类的能力,但是不能让外人看到其本质,需要私生子自己包装一下,也就是,将父类的接口包含在自己的对外接口的定义体内部。这样,私生子有父类的能力,但是外人也看不到其本质。

目的与好处

  1. 封装:私有继承可以帮助实现更好的封装。当你不希望,基类的接口暴露给用户时,可以选择私有继承。

  2. 实现“是一个”的关系:私有继承可以表示一种“实现”关系,而不是“是一个”关系。这意味着,派生类可以实现基类的功能,但是不能将基类的接口暴露给外部。也就是,私生子可以拥有父类的能力,但是对外不能承认它的身份,不能有父类的标志。所以,是实现 "是一个"的关系。

  3. 控制访问:通过私有继承,派生类可以控制对基类成员的访问,确保,只有在派生类内部,可以访问基类的公有成员和保护成员。而不能通过派生类的实例对象,访问,基类的公有成员和保护成员!

示例代码

下面是一个示例,演示私有继承的用法:

#include <iostream>
#include <string>// 基类 Base
class Base {
public:void display() const {std::cout << "Base class display function." << std::endl;}protected:std::string protectedMember = "Protected Member";
};// 派生类,私有继承  基类 Base
class Derived : private Base {
public:void show() {// 可以访问基类的公有和保护成员display(); // 调用/访问,基类的公有成员 ---> display()方法std::cout << "Accessing: " << protectedMember << std::endl; // 访问基类的保护成员}
};int main() {Derived derived; // 创建派生类的实例对象derived.show(); // 访问派生类的公开成员show()// 下面这行代码会报错,因为 display() 是基类的公有成员,在派生类 Derived 中是私有的// derived.display();  // 不能在类的外部,访问类的私有成员return 0;
}

说明

  1. 基类 Base

    • 包含一个公有成员 display() 和一个保护成员 protectedMember
  2. 派生类 Derived

    • 私有继承 Base。这意味着,基类 Base 的公有和保护成员,在派生类 Derived 中,变为私有成员。
    • 在派生类 Derived的公开成员show() 中,派生类 Derived 可以访问基类Base 的 公开成员display() 方法,以及保护成员 protectedMember
  3. main 函数中

    • 创建了派生类Derived 的一个实例对象,并调用派生类的公开成员,show() 方法,成功访问了基类的公开和保护成员。
    • 尝试直接调用 derived.display() ,会导致编译错误,因为基类的公开成员 display(),在派生类Derived 中,是私有的,不暴露给外部访问。

运行结果

运行上述代码,输出将是:

Base class display function.
Accessing: Protected Member

这表明,私有继承,成功地封装了基类的接口,只有在派生类Derived 的内部,可以访问基类的公有和保护成员。通过这种方式,可以实现更严格的访问控制和封装。

2. "基类被子类私有继承后,基类的公有成员依然能够被子类访问。"这个对吗?为什么?

对!

基类被派生类私有继承后,基类的公有成员和保护成员,依然能够在派生类的内部被访问。

原因

在 C++ 中,私有继承,意味着,派生类的实例对象不能直接访问基类的公有成员和保护成员!因为,此时,基类的公开成员和保护成员,在派生类中,变成私有的!但是,在派生类的定义体内部,可以访问基类的公有成员和保护成员。这也表明,类的私有成员,只有在类的定义体内部,才可以被访问!

示例代码

下面是一个示例,展示一下,基类的公有成员,如何在私有继承的情况下,被子类访问。

#include <iostream>
#include <string>// 基类 Base
class Base {
public:void show() const {std::cout << "Base class show function." << std::endl;}std::string name = "Base Class";
};// 派生类Derived,私有继承  基类 Base
class Derived : private Base {
public:void accessBaseMembers() {// 可以访问基类的公有成员show(); // 调用/访问,基类的公有成员 ---> show()方法std::cout << "Accessing base member: " << name << std::endl; // 访问基类的公有成员变量}
};int main() {Derived derived; // 创建派生类的实例对象derived.accessBaseMembers(); // 访问派生类的公开成员accessBaseMembers()// 下面这行代码会报错,因为 show() 是基类的公有成员,但在派生类 Derived 中是私有的// derived.show();  // 不能在类的外部,访问类的私有成员 return 0;
}

说明

  1. 基类 Base

    • 定义了一个公有成员函数 show() 和一个公有成员变量 name
  2. 派生类 Derived

    • 私有继承 Base。这意味着, Base 的公有成员,在 Derived 中变成了 Derived 的私有成员。
    • accessBaseMembers() 成员函数中,派生类可以访问基类的公有成员函数 show() 和公有成员变量 name
  3. main 函数中

    • 创建了派生类Derived 的一个实例对象,并调用派生类Derived的公有成员 accessBaseMembers() ,成功访问了,基类的公有成员。
    • 尝试直接调用 derived.show(),会导致编译错误,因为 show() 在 派生类Derived 中,是私有的,不可在派生类Derived 的外部访问。

运行结果

运行上述代码,输出将是:

Base class show function.
Accessing base member: Base Class

这表明,即使基类被私有继承,派生类仍然可以在自己的定义体内部,访问基类的公开成员( 和保护成员 )。

3. 私有继承和公有继承有什么区别?

私有继承和公有继承是 C++ 中两种不同的继承方式,它们在访问控制基类与派生类之间的关系,这两点上,有显著区别。以下是它们的主要区别:

(1) 访问控制

  • 公有继承

    • 基类的公有成员,在派生类中,仍然是公有的。
    • 基类的保护成员,在派生类中,仍然是保护的。
    • 基类的私有成员,派生类不可访问。
  • 私有继承

    • 基类的公有成员,在派生类中,变为私有的。
    • 基类的保护成员,在派生类中,变为私有的。
    • 基类的私有成员,派生类不可访问。

(2) 关系的表达

  • 公有继承

    • 明确表示,“是一个”(is-a)关系。例如,DogAnimal 的一种。
  • 私有继承

    • 明确表示,“实现”(is-implemented-in-terms-of)关系,不承认(隐含) “是一个”关系。通常用于表示,派生类使用基类的功能,但不希望将基类的接口暴露给外部

(3) 访问方式

  • 公有继承

    • 可以通过派生类的实例对象,直接访问,基类的公有成员。
  • 私有继承

    • 不能通过派生类的实例对象,直接访问,基类的公有成员;只能在派生类的定义体内部,访问基类的公有成员和保护成员。因此,此时,基类的公开成员和保护成员,在派生类中,变成( 派生类的 )私有的了!

示例代码

以下是一个示例,展示,公有继承和私有继承的区别:

#include <iostream>// 基类 Base
class Base {
public:void publicMethod() {std::cout << "Base public method." << std::endl;}protected:void protectedMethod() {std::cout << "Base protected method." << std::endl;}
};// 派生类 PublicDevired  公开继承  Base类
class PublicDerived : public Base {
public:void accessBaseMethods() {publicMethod();      // 可以访问 基类的公有成员protectedMethod();   // 可以访问 基类的保护成员}
};// 派生类 PrivateDerived  私有继承  Base类
class PrivateDerived : private Base {
public:void accessBaseMethods() {publicMethod();      // 可以访问 基类的公有成员protectedMethod();   // 可以访问 基类的保护成员}
};int main() {PublicDerived pubDerived; // 创建 派生类 PublicDerived的实例对象pubDerived.accessBaseMethods(); // 访问派生类的公有成员// 下面这行代码会编译通过pubDerived.publicMethod(); // 可以直接访问,基类的公有成员PrivateDerived privDerived; // 创建 派生类 PrivateDerived的实例对象privDerived.accessBaseMethods(); // 访问派生类的公有成员// 下面这行代码会报错,因为 publicMethod 在 派生类 PrivateDerived 中是私有的// privDerived.publicMethod(); // 不能在类的外部,访问类的私有成员return 0;
}

运行结果

运行上述代码,输出将是:

Base public method.
Base protected method.Base public method.Base public method.
Base protected method.

总结

  • 公有继承:基类的公有成员,在派生类中,仍然是公有的,允许在派生类的外部访问;表示派生类与基类之间,“是一个”的关系。
  • 私有继承:基类的公有成员,在派生类中,变为私有的,在派生类的外部无法访问,只能在派生类内部访问;表示派生类与基类之间,“实现”的关系。

4. 派生类如何访问基类的私有成员?

在 C++ 中,派生类无法直接访问,基类的私有成员。每一个类,其私有成员,只能在自己内部( 自己定义体内部 ),被访问;不能在自己外部( 自己定义体外部 )被访问!

派生类访问基类私有成员的方式

尽管派生类不能直接访问基类的私有成员,但可以通过以下几种方式,间接访问基类的私有成员:

  1. 通过基类的公开成员方法或保护成员方法

    • 基类可以提供公开成员方法或保护成员方法,在这些方法内部,可以访问基类的私有成员。派生类可以通过调用这些基类的公开成员方法或保护成员方法,来间接访问基类的私有成员。
  2. 通过基类的友元函数

    • 如果一个友元函数被定义在基类中,它可以访问基类的私有成员。派生类可以通过调用,这个基类的友元函数,来访问基类的私有成员。

示例代码1:通过基类的公开成员方法或保护成员方法

以下是一个示例,展示,派生类如何通过基类的公开成员方法,间接访问基类的私有成员:

#include <iostream>// 基类 Base
class Base {
private:int privateValue = 42; // 基类 Base的 私有成员protected:int protectedValue = 24; // 基类 Base的 保护成员public:// 基类 Base的公有成员方法,其内部,可以访问基类 Base的私有成员int getPrivateValue() const {return privateValue;}
};// 派生类 Derived 公开继承 基类 Base
class Derived : public Base {
public:void showValues() {// 不能直接访问,基类 Base的私有成员 privateValue// std::cout << privateValue; // 这一行会报错// 可以通过,基类 Base的公有成员方法 getPrivateValue(),来访问,基类Base的私有成员std::cout << "Private Value: " << getPrivateValue() << std::endl;std::cout << "Protected Value: " << protectedValue << std::endl; // 可以直接访问,基类Base的保护成员}
};int main() {Derived derived; // 创建 派生类 PublicDerived的实例对象derived.showValues(); // 访问 派生类的公有成员方法return 0;
}

运行结果

运行上述代码,输出将是:

Private Value: 42
Protected Value: 24

总结

  • 直接访问:派生类不能直接访问基类的私有成员。
  • 间接访问
    • 通过基类的公有成员方法或保护成员方法,来访问,基类的私有成员。
    • 通过基类的友元函数,来访问,基类的私有成员。

这种设计,确保了,数据的封装性和安全性,只有通过特定的接口,才能访问类的私有数据。

示例代码2:通过基类的友元函数

下面是一个详细的示例,展示,派生类如何通过基类的友元函数,来间接访问/调用,基类的私有成员。

#include <iostream>// 基类Base
class Base {
private:int privateValue = 42; // 基类Base的 私有成员public:// 声明 基类Base的友元函数 accessPrivateValue( 在类的内部声明 )friend void accessPrivateValue(const Base& b);
};// 基类Base的友元函数 accessPrivateValue的定义( 在类的外部定义 )
void accessPrivateValue(const Base& b) {// 在友元函数内部,可以访问,基类Base的私有成员std::cout << "Accessing Base's private value: " << b.privateValue << std::endl;
}// 派生类Derived 公开继承 基类Base
class Derived : public Base {
public:// 派生类Derived的 公有成员方法void showPrivateValue() {// 通过基类Base的友元函数,来访问基类Base的私有成员accessPrivateValue(*this); // 传递,当前派生类Derived的实例对象(哪个Derived的实例对象,调用showPrivateValue()方法,传递的就是,该Derived实例对象)}
};int main() {Derived derived;derived.showPrivateValue(); // 调用派生类的公有成员方法return 0;
}

代码解析

  1. 基类 Base

    • 定义了一个私有成员方法 privateValue
    • 声明了一个友元函数 accessPrivateValue;基类Base的这个友元函数,可以访问基类Base的私有成员。
  2. 基类Base友元函数 accessPrivateValue

    • 声明在基类Base的内部,定义在基类Base的外部。由于它是 基类Base 的友元函数,因此可以访问 基类Base 的私有成员privateValue
  3. 派生类 Derived

    • 继承基类 Base
    • 定义了一个公有成员方法 showPrivateValue,这个方法内部,调用了基类Base的友元函数 accessPrivateValue;基类Base的友元函数 accessPrivateValue,将,当前派生类Derived的实例对象(*this)作为参数,进行传递。( 哪个Derived的实例对象,调用showPrivateValue()方法,传递的就是,该Derived实例对象 )
  4. main 函数

    • 创建了一个 Derived 类的实例对象 derived
    • 调用 derived.showPrivateValue(),这将输出,基类Base的私有成员的值。

运行结果

运行上述代码,输出将是:

Accessing Base's private value: 42

总结

  • 友元函数:在基类Base的内部,将 accessPrivateValue 函数声明为 基类Base 的友元函数,该函数便获得了,访问 基类Base的私有成员privateValue 的权限。( 声明在 基类Base的内部,定义在 基类Base的外部 )
  • 派生类访问:派生类 Derived 通过调用,基类Base的友元函数 accessPrivateValue,间接访问了,基类Base的私有成员 privateValue

这种设计使得,基类的私有数据受到保护,同时提供一种安全的方式,让派生类通过友元函数,访问基类的私有数据。

5. 在使用基类的友元函数时,派生类公有继承基类时,与私有继承基类时,会有什么区别?

在 C++ 中,基类的友元函数的使用,与派生类继承基类的方式( 公有继承、私有继承等 )有关,主要体现在 访问权限友元关系上。
以下是,派生类公有继承基类、派生类私有继承基类,在使用基类的友元函数时的一些区别:

  • 公有继承

    • 基类的友元函数内部,可以访问,基类的所有公有成员、所有保护成员、所有私有成员;
    • 公有继承时,基类的公有成员和保护成员,在派生类中,也是公有的;在派生类的外部,可以调用基类的友元函数,传递派生类的实例对象,来访问基类的所有公有成员、所有保护成员、所有私有成员;
  • 私有继承

    • 基类的友元函数内部,可以访问,基类的所有公有成员、所有保护成员、所有私有成员;
    • 私有继承时,基类的公有成员和保护成员,在派生类中,是私有的;在派生类的外部,不能调用基类的友元函数,来传递派生类的实例对象,以访问基类的公有成员和私有成员。因为,此时,基类的公有成员和保护成员,在派生类中,是私有的,不能在类的外部,访问类的私有成员!
    • 基类的友元函数,只能在派生类的内部被调用,传递派生类的实例对象,来访问基类的所有公有成员、所有保护成员、所有隐私成员;

派生类对基类的私有继承,或者公开继承,不会影响基类的友元函数内部,对基类的所有成员的访问!有影响的是,公有继承的情况下,可以在派生类的外部,直接调用基类的友元函数,传递派生类的实例对象!而私有继承的情况下,不可以在派生类的外部,直接调用基类的友元函数,传递派生类的实例对象;只能在派生类的内部,直接调用基类的友元函数,传递派生类的实例对象!

示例代码1:公有继承和私有继承在友元函数使用上的区别

下面是一个示例代码,展示公有继承和私有继承在友元函数使用上的区别:

#include <iostream>// 基类 Base
class Base {
public:int publicValue = 10;protected:int protectedValue = 20;// 声明 友元函数 friendFunctionfriend void friendFunction(Base& b);
};// 派生类 PublicDerived  公开继承  基类 Base
class PublicDerived : public Base {
public:void show() {// 访问基类 Base的公开成员 publicVaulestd::cout << "PublicDerived accessing Base: " << publicValue << std::endl; }
};// 派生类 PrivateDerived  私有继承  基类 Base
class PrivateDerived : private Base {
public:void show() {// 访问基类 Base的公开成员 publicVaulestd::cout << "PrivateDerived accessing Base: " << publicValue << std::endl;}
};// 基类 Base的友元函数 的定义
void friendFunction(Base& b) {std::cout << "Friend function accessing Base: " << b.publicValue << std::endl;std::cout << "Friend function accessing Base: " << b.protectedValue << std::endl;
}int main() {Base base; // 创建一个基类 Base的实例对象friendFunction(base); // 友元函数 可以直接传递 基类 Base的实例对象,访问 基类 Base 的所有成员PublicDerived pubDerived; // 创建派生类 PublicDerived的实例对象pubDerived.show(); // 访问派生类 PublicDerived的公有成员PrivateDerived privDerived; // 创建派生类 PrivateDerived的实例对象privDerived.show(); // 访问派生类 PrivateDerived的公有成员// 在派生类 PublicDerived的外部,直接调用基类 Base的友元函数,传递派生类 PublicDerived的实例对象friendFunction(pubDerived);// friendFunction(privDerived); // 这行会报错,派生类 PrivateDerived 私有继承 基类 Base!所以,不能在派生类 PrivateDerived的外部,直接调用基类 Base的友元函数,传递派生类 PublicDerived的实例对象!return 0;
}

运行结果

运行上述代码,输出将是:

Friend function accessing Base: 10
Friend function accessing Base: 20
PublicDerived accessing Base: 10
PrivateDerived accessing Base: 10
Friend function accessing Base: 10
Friend function accessing Base: 20

在 C++ 中,当使用私有继承时,只能在派生类的成员函数中,调用基类 的友元函数,传递 派生类的实例对象!
下面是一个详细的示例代码来说明这一点。

示例代码2:私有继承时,只能在派生类的成员函数中,调用基类 的友元函数,传递 派生类的实例对象!

#include <iostream>// 基类 Base
class Base {
public:void show() {std::cout << "Base class show function." << std::endl;}// 声明 基类 Base的友元函数friend void friendFunction(Base& b);
};// 派生类 Derived  私有继承  基类 Base
class Derived : private Base {
public:void display() {std::cout << "Derived class display function." << std::endl;// 在派生类的成员函数中可以访问基类的公有成员show(); // 访问基类的公有成员}// 提供一个对外的公开接口函数,在内部,调用基类 Base的友元函数void callFriendFunction() {friendFunction(*this); // 调用基类 Base的友元函数,传递派生类的实例对象}
};// 定义基类 Base的友元函数
void friendFunction(Base& b) {b.show();  // 在基类 Base的友元函数内部,可以访问 基类 Base 的所有成员
}int main() {Base b; // 创建基类 Base的实例对象friendFunction(b); // 直接在基类 Base的外部,调用其友元函数,传递基类 Base的实例对象Derived d; // 创建派生类 Derived的实例对象// friendFunction(d); // 这行会报错!派生类 Derived 私有继承 基类 Base!所以,不能在派生类 Derived的外部,直接调用基类 Base的友元函数,传递派生类 Derived的实例对象!d.display(); // 调用派生类 Derived的公开成员函数d.callFriendFunction(); // 通过派生类Derived的对外公开成员函数,间接调用基类 Base的友元函数return 0;
}

代码解析

  1. 基类 Base

    • 定义了一个公有成员函数 show(),输出一条信息。
    • 声明了一个友元函数 friendFunction(),允许其访问 Base 的所有成员。
  2. 派生类 Derived

    • 私有继承 private Base,这意味着, Base 的公有成员和保护成员在 Derived 中都会变为私有的。
    • 定义了一个公开成员函数 display(),可以访问基类的公有成员 show()
    • 定义了一个公开成员函数 callFriendFunction(),用于间接调用基类 Base的友元函数 friendFunction()
  3. 友元函数 friendFunction()

    • 接受一个 Base 类型的引用( 可以是基类 Base的实例对象,可以是基类 Base的子类的实例对象 ),可以访问 Base 的公有成员 show()
  4. main() 函数

    • 创建了一个基类 Base 的实例对象 b,在基类 Base 的外部,直接调用其友元函数 friendFunction(),传递基类 Base 的实例对象;
    • 创建了一个派生类 Derived 的实例对象 d,在派生类 Derived 的外部,直接调用基类 Base 的友元函数 friendFunction(), 会导致错误,因为派生类 Derived 是私有继承基类 Base ,所以,不能在派生类 Derived 的外部,直接调用 基类Base的友元函数!
    • 调用派生类 Derived 的公开成员函数 display(),可以调用 基类Base的友元函数 friendFunction()

总结

  • 公有继承

    • 可以在派生类的外部,直接调用基类的友元函数,传递派生类的实例对象;
  • 私有继承

    • 无法在派生类的外部,直接调用基类的友元函数,传递派生类的实例对象!但是,可以在派生类的对外公开成员函数内部,调用基类的友元函数!从而,实现,间接调用基类的友元函数!

这种区别,使得,在设计类的接口和访问控制时,选择合适的继承方式和友元函数的使用,变得尤为重要。

相关文章:

什么是私有继承

私有&#xff0c;公有&#xff0c;针对类而言&#xff1b; 私有( private )的成员&#xff0c;自己的&#xff0c;只能在自己内部( 类的定义体内部 )访问&#xff0c;外部( 类的定义体外部 )不能访问/调用&#xff1b; 公有( 或者说公开&#xff0c;public )的成员&#xff0…...

Scratch编程:开启智能硬件控制的大门

标题&#xff1a;“Scratch编程&#xff1a;开启智能硬件控制的大门” 在当今数字化时代&#xff0c;编程不仅仅是与计算机的交互&#xff0c;更是与物理世界的连接。Scratch&#xff0c;这款由麻省理工学院媒体实验室开发的视觉化编程语言&#xff0c;以其易学易用的特性&…...

机器学习第十二章-计算学习理论

目录 12.1基础知识 12.2 PAC学习 12.3有限假设空间 12.3.1可分情形 12.3.2不可分情形 12.4VC维 12.5 Rademacher复杂度 12.1基础知识 计算学习理论研究的是关于通过"计算"来进行"学习"的理论&#xff0c;即关于机器学习的理论基础&#xff0c;其目的…...

Java-自定义注解操作日志记录处理(@Pointcut注解不是必须的)

在Java中,使用自定义注解结合Spring AOP来实现操作日志记录是一种常见的做法。这种方式可 以帮助你轻松地在不修改业务代码的情况下增加日志记录的功能。 下面我将详细介绍如何定义一个自定义注解,并结合Spring AOP来实现操作日志记录的功能。 1. 定义自定义注解 首先,我…...

【c++】深入理解别名机制--引用

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、引用的概念和定义 二、引用的特性 三、引用的实用性 1.引用传参 2.引用做返回值 2.1 引用做返回值的作用 2.2 引用坍缩问题、悬挂引用问…...

简便的qemu img扩容方法

虚拟机用着用着磁盘空间就不够了&#xff0c;那就要想办法增加磁盘空间大小 了。在虚拟机本身磁盘的基础上直接增加空间大小最简便&#xff0c;于是记录一下方法。 首先&#xff0c;在虚拟机关机状态下&#xff0c;使用qemu-img命令给虚拟机的磁盘镜像增加虚拟空间5GB&#xff…...

EPERM: operation not permitted,

这个错误提示 EPERM: operation not permitted, mkdir C:\Program Files\nodejs\node_global\node_modules\pnpm_tmp 通常是因为权限不足导致的。在 Windows 系统中&#xff0c;C:\Program Files\ 目录通常需要管理员权限才能写入。 要解决这个问题&#xff0c;你可以尝试以下…...

将Centos 8 Linux内核版本升级或降级到指定版本

本文以centos 8.0为例&#xff0c;内核版本为4.18.0-80.el8.x86_64&#xff0c;升级到内核版本为4.18.0-80.4.2.el8_0.x86_64。 1.查看当前系统版本信息 [rootcentos80-1905 ~]# uname -sr Linux 4.18.0-80.el8.x86_642.在网站&#xff1a;https://vault.centos.org/里面下载…...

小程序商城被盗刷,使用SCDN安全加速有用吗?

在电子商务蓬勃发展的今天&#xff0c;小程序商城因其便捷性和灵活性成为商家和消费者的新宠。然而&#xff0c;随着其普及&#xff0c;小程序商城的安全问题也日益凸显&#xff0c;尤其是盗刷现象频发&#xff0c;给商家和用户带来了巨大损失。面对这一挑战&#xff0c;是否可…...

nginx的基本使用与其日志

文章目录 1.nginx编译安装脚本2.nginx平滑升级&#xff0c;以及其步骤3.nginx核心配置&#xff0c;及实现nginx多虚拟主机4.nginx日志格式定制5.nginx反向代理及https安全加密6.基于LNMP和Redis的phpmyadmin的会话保持&#xff0c;以及其完整步骤 1.nginx编译安装脚本 #编译安…...

linux | 苹果OpenCL(提高应用软件如游戏、娱乐以及科研和医疗软件的运行速度和响应)

点击上方"蓝字"关注我们 01、引言 >>> OpenCL 1.0 于 2008 年 11 月发布。 OpenCL 是为个人电脑、服务器、移动设备以及嵌入式设备的多核系统提供并行编程开发的底层 API。OpenCL 的编程语言类似于 C 语言。其可以用于包含 CPU、GPU 以及来自主流制造商如 …...

算法-UKF中Sigma点生成

void UKF::MakeSigmaPoints() {Eigen::VectorXd x_aug_ Eigen::VectorXd(n_x_);x_aug_.head(n_x_) x_;Eigen::MatrixXd P_aug Eigen::MatrixXd::Zero(n_x_, n_x_);// 转成正定矩阵P_aug pdefinite_svd(P_);// LLT分解Eigen::MatrixXd L P_aug.llt().matrixL();sigma_point…...

精选五款热门骨传导耳机分享,让你避免踩坑的陷阱

因为骨传导耳机独特的佩戴方式和声音的传播方式&#xff0c;受到了小耳、油耳以及运动爱好者的的喜爱&#xff0c;但也由于市面上的骨传导耳机品牌越来越多&#xff0c;很多朋友不知道该怎么选择&#xff0c;今天我挑选出市面上体验感较好&#xff0c;各方面比较出色的骨传导给…...

「字符串」前缀函数|KMP匹配:规范化next数组 / LeetCode 28(C++)

概述 为什么大家总觉得KMP难&#xff1f;难的根本就不是这个算法本身。 在互联网上你可以见到八十种KMP算法的next数组定义和模式串回滚策略&#xff0c;把一切都懂得特别混乱。很多时候初学者的难点根本不在于这个算法本身&#xff0c;而是它令人痛苦的百花齐放的定义。 有…...

python人工智能002:jupyter基本使用

小知识&#xff1a;将jupyter修改为中文&#xff0c;修改用户变量&#xff0c; 注意是用户变量&#xff0c;不是系统变量 新增用户变量 变量名&#xff1a;LANG 变量值&#xff1a;zh_CN.UTF8 然后重启jupyter 上一章的软件安装完成之后&#xff0c;就可以创建文件夹来学习写…...

Linux使用 firewalld管理防火墙命令

Linux 发行版中使用的动态防火墙管理工具。使用 firewalld&#xff0c;你可以查看防火墙状态、当前配置的规则以及开放的端口。以下是一些常用的 firewalld 命令来管理和查看防火墙状态及端口配置。 1. 查看防火墙状态 检查 firewalld 是否正在运行 sudo systemctl status f…...

二叉树(三)

一、二叉树的遍历 二叉树遍历是按照某种特定的规则&#xff0c;依次对二叉树中的结点进行相应的操作&#xff0c;并且每个结点只操作一次。 1.前序遍历&#xff08;先根遍历&#xff09; 前序遍历&#xff08;Preorder Traversal也叫先序遍历&#xff09;——根、左子树、右…...

05--kubernetes组件与安装

前言&#xff1a;终于写到kubernetes&#xff08;k8s&#xff09;&#xff0c;容器编排工具不止k8s一个&#xff0c;它的优势在于搭建集群&#xff0c;也是传统运维和云计算运维的第一道门槛&#xff0c;这里会列出两种安装方式&#xff0c;详细步骤会在下文列出&#xff0c;文…...

EmguCV学习笔记 VB.Net和C# 下的OpenCv开发 C# 目录

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…...

探索TensorFlow:深度学习的未来

标题&#xff1a;探索TensorFlow&#xff1a;深度学习的未来 在当今快速发展的人工智能领域&#xff0c;TensorFlow无疑是最耀眼的明珠之一。TensorFlow是由Google Brain团队开发的一个开源机器学习框架&#xff0c;它以其强大的灵活性、易用性和高效的性能&#xff0c;迅速成…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...