万文c++继承

news2025/5/15 5:36:38

1、继承的概念与定义

1.1继承的概念

继承:是c++代码复用的手段,允许在原有的基础上扩展,在此之前都是函数层次的复用,继承是类设计层次的复用。

下面有两个类Student和Teacher都有姓名/地址/电话/年龄等成员变量。都有identity身份,设计到两个类⾥⾯就是冗余的。当然他们 也有⼀些不同的成员变量和函数,⽐如⽼师独有成员变量是职称,学⽣的独有成员变量是学号;学⽣ 的独有成员函数是学习,⽼师的独有成员函数是授课。

#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
	void identity()	{}
	void study(){}
protected:
	string _name;
	string _address;
	string _tel;
	int _age;
	int _stuid;
};
class Teacher
{
public:
	void identity(){}
	void teaching(){}
protected:
	string _name;
	string _address;
	string _tel;
	int _age;
	int _stuid;
};
int main()
{

	return 0;
}

下⾯我们公共的成员都放到Person类中,Student和teacher都继承Person,就可以复⽤这些成员,就 不需要重复定义了,省去了很多⿇烦。

class Person
{
public:
	void identity()	{	}
protected:
	string _name="王五";
	string _address;
	string _tel;
	int _age;
};
class Student:public Person
{
public:
	void print()
	{
		cout << _name << endl;
	}
	void study() { }
protected:
	
	int _stuid;

};
class Teacher:public Person
{
public:

	void teaching()	{	}
protected:
	string title;

};
int main()
{
	Student s;
	s.print();

	return 0;
}

 1.2 继承定义

1.2.1 定义下⾯我们看到Person是基类,也称作⽗类。Student是派⽣类,也称作⼦类。(因为翻译的原因,所以 既叫基类/派⽣类,也叫⽗类/⼦类)

 1.2.2 继承基类成员访问⽅式的变化

如何记忆:记得权限大小 public>protected>private 起中private是最小的 所以它和谁配都小,成员变量存在但不能访问。由此可见谁小听谁的。 

有一种最有趣,基类private成员在派⽣类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派⽣类 中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。 例子在第二个代码段。

1.3 继承类模板

如何实现用继承写一段栈呢

namespace bit
{
	//template<class T>
	//class vector
	//{};
	// stack和vector的关系,既符合is-a,也符合has-a 
	template<class T>
	class stack : public vector<T>
	{
	public:
		void push(const T& x)
		{
			// 基类是类模板时,需要指定⼀下类域, 
			// 否则编译报错:error C3861: “push_back”: 找不到标识符
			// 因为stack<int>实例化时,也实例化vector<int>了 
 // 但是模版是按需实例化,push_back等成员函数未实例化,所以找不到 
			vector<T>::push_back(x);
			//push_back(x);
		}
		void pop()
		{
			vector<T>::pop_back();
		}
		const T& top()
		{
			return vector<T>::back();
		}
		bool empty()
		{
			return vector<T>::empty();
		}
	};
}
int main()
{
	bit::stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
	return 0;
}

注意当我们想写一个通用的迭代器打印的时候,容易发生编译器困惑的错误❌。

在这段 C++ 模板代码里,typename 不加会报错,

是因为编译器无法确定 Container::const_iterator 究竟是类型还是成员变量 。

在 C++ 模板中,当模板未实例化时,编译器不知道模板参数 Container 具体是什么类型。Container::const_iterator 这种嵌套依赖类型(其具体类型依赖于 Container ),它有两种可能身份:

  • 类型:在类似 std::vector 或 std::list 这些标准容器中,const_iterator 是一种类型,用于定义常量迭代器,能遍历容器元素。

  • 成员变量:假如 Container 是个自定义类,它里面恰好有个叫 const_iterator 的成员变量,编译器在模板实例化前无法知晓。

编译器没办法在编译阶段,模板还没实例化、不知道 Container 确切类型的情况下,自动判断出 Container::const_iterator 到底是类型还是成员变量 。如果不明确告诉编译器它是类型,编译器就会困惑,不知道该怎么处理这行代码,进而报错 。

解决方法

1 typename:关键字就是专门用来告知编译器,它后面跟着的是一个类型 。

2 写auto  倒数第二个有讲解


2.基类和派⽣类间的转换

在C++中,公有继承的派生类对象可以赋值给基类的指针或引用,这种现象被称为切片(Slicing)/切割

2.1 什么是切片?

想象你有一个完整的三明治(派生类对象),它包含面包(基类部分)、火腿、蔬菜和奶酪(派生类特有部分)。
当你将整个三明治递给一个只吃面包的人(基类指针/引用),他只会拿走面包部分,而火腿和奶酪会被“切掉”并丢弃。
这就是切片:基类指针或引用只能访问派生类对象中属于基类的部分,派生类特有的成员被“切无法通过基类接口访问。

#include <iostream>
using namespace std;

// 基类:Animal
class Animal {
public:
    string name;
    int age;
    Animal(string n, int a) : name(n), age(a) {}
};

// 派生类:Dog(公有继承Animal)
class Dog : public Animal {
public:
    string breed;  // 派生类特有成员(品种)
    Dog(string n, int a, string b) : Animal(n, a), breed(b) {}
};

int main() {
    Dog dog("Buddy", 3, "Golden Retriever");

    // 基类引用绑定到派生类对象(切片发生)
    Animal& animalRef = dog;
    Animal* animalPtr = &dog;

    Animal animal= dog;//在后面的基类拷贝构造有


    // 可以访问基类成员
    cout << "Name: " << animalRef.name << endl;  // 输出:Buddy
    cout << "Age: " << animalPtr->age << endl;   // 输出:3

    // 无法访问派生类特有成员(编译错误)
    // cout << "Breed: " << animalRef.breed << endl;  // 错误!
    // cout << "Breed: " << animalPtr->breed << endl;  // 错误!

    return 0;
}

2.2为什么需要切片?

  • 统一接口:将不同派生类对象统一视为基类对象处理,提高代码通用性。
    例如:所有动物(基类)都可以调用eat(),而具体实现由派生类(狗、猫)决定。

  • 避免内存错误:强制类型安全,防止通过基类接口误操作派生类特有数据,没有临时变量参与。

2.3常见实例

函数参数传递

void printAnimal(const Animal& animal) {
    cout << "Name: " << animal.name << ", Age: " << animal.age << endl;
}

int main() {
    Dog dog("Buddy", 3, "Golden Retriever");
    printAnimal(dog);  // 传递派生类对象给基类引用(切片发生)
}

容器存储

vector<Animal> animals;
Dog dog("Buddy", 3, "Golden Retriever");
animals.push_back(dog);  // 切片:容器中只存储Animal部分数据

3.继承中的作⽤域 

3.1 独立作用域:基类和派生类各占山头

基类和派生类就像两个独立房间,各自定义的成员(变量/函数)默认只在各自房间可见。

class Base {
public:
    int a = 10;
    void print() { cout << "Base: " << a << endl; }
};

class Derived : public Base {
public:
    int a = 20;       // 隐藏基类的a
    void print() { cout << "Derived: " << a << endl; } // 隐藏基类的print()
};

3.2 同名成员:派生类“盖住”基类

当基类和派生类有同名成员时,派生类成员会直接覆盖基类成员,如同用纸盖住桌上的字。
访问规则

  • 默认访问派生类成员。

  • 要访问基类成员,需用基类名::成员名显式指明。

    Derived d;
    cout << d.a << endl;          // 输出20(派生类的a)
    cout << d.Base::a << endl;    // 输出10(显式访问基类的a)
    d.print();                    // 调用派生类的print()
    d.Base::print();              // 显式调用基类的print()

    3.3 函数隐藏:只看函数名,不管参数

  • 只要函数名相同,无论参数是否相同,派生类函数都会隐藏基类所有同名函数。
class Base {
public:
    void func(int x) { cout << "Base::func(int)" << endl; }
};

class Derived : public Base {
public:
    void func() { cout << "Derived::func()" << endl; }
    // 隐藏了Base::func(int)
};

Derived d;
d.func();            // 正确:调用Derived::func()
// d.func(5);       // 错误!基类的func(int)被隐藏
d.Base::func(5);     // 正确:显式调用基类函数

3.4继承作⽤域相关选择题

3.2.1 A和B类中的两个func构成什么关系()

A. 重载 B. 隐藏 C.没关系

3.2.2 下⾯程序的编译运⾏结果是什么()

A. 编译报错 B. 运⾏报错 C. 正常运⾏

3.2.2当子类(B)定义了一个与父类(A)同名的函数(无论参数是否相同),子类会隐藏父类的所有同名函数。因此:b.fun(10);走的是B,b.fun();走的也是B但是没有提供所以编译报错,运行报错是代码本身有语法问题。

答案B. 隐藏  A. 编译报错

class A
{
public:
	void fun()
	{
		cout << "func()" << endl;
	}
};
class B : public A
{
public:
	void fun(int i)
	{
		cout << "func(int i)" << i << endl;
	}
};
int main()
{
	B b;
	b.fun(10);
	b.fun();
	return 0;
};

4.继承中派生类的常见成员函数

4.1构造函数

1. 派生类构造函数必须调用基类构造函数

如果基类没有默认构造函数(即无参构造函数)派生类无需显示调用,但若没有默认构造有带参构造函数,派生类必须在初始化列表中显式调用基类的带参构造函数。

class Base {
public:
    Base(int value) : data(value) {} // 基类只有带参构造函数
private:
    int data;
};

class Derived : public Base {
public:
    Derived(int baseValue, int derivedValue) 
        : Base(baseValue), derivedData(derivedValue) {} // 显式调用基类构造
private:
    int derivedData;
};
2.派生类对象初始化顺序:基类构造→派生类构造

创建派生类对象时,先调用基类的构造函数,再调用派生类的构造函数。

class Base {
public:
    Base() { cout << "Base Constructor" << endl; }
};

class Derived : public Base {
public:
    Derived() { cout << "Derived Constructor" << endl; }
};

// 使用示例
int main() {
    Derived d;
    return 0;
}

  • 基类部分必须在派生类部分初始化之前完成构造,因为派生类可能依赖基类的状态。

4.2拷贝构造

1.派生类拷贝构造函数必须调用基类拷贝构造函数

派生类的拷贝构造函数需要显式调用基类的拷贝构造函数,以复制基类部分的成员。

class Base {
public:
    Base(int value) : data(value) {}
    Base(const Base& other) : data(other.data) {} // 基类拷贝构造函数
private:
    int data;
};

class Derived : public Base {
public:
    Derived(int value) : Base(value), derivedData(0) {}
    
    // 派生类拷贝构造函数
    Derived(const Derived& other) 
        : Base(other), // 显式调用基类拷贝构造
          derivedData(other.derivedData) {}
private:
    int derivedData;
};
  • 当创建Derived对象的拷贝时,Derived的拷贝构造函数必须先调用Base的拷贝构造函数,确保基类部分被正确复制。

  • 若不显式调用Base(other),基类部分将使用默认构造函数初始化(而非复制),导致数据丢失。

  • 如果基类没有定义拷贝构造函数,编译器会自动生成一个浅拷贝的拷贝构造函数。

  • 浅拷贝足够时:无需自定义拷贝构造函数(如基类只有值类型成员)。

  • 深拷贝需求:若基类包含动态资源(如指针),必须自定义拷贝构造函数,否则会导致多个对象共享同一资源,析构时重复释放。

4.3赋值运算符

派生类的operator=必须调用基类的operator=

派生类的赋值运算符需要显式调用基类的赋值运算符,以复制基类部分的成员。

class Base {
public:
    Base& operator=(const Base& other) {
        if (this != &other) {
            data = other.data;
        }
        return *this;
    }
private:
    int data;
};

class Derived : public Base {
public:
    Derived& operator=(const Derived& other) {
        if (this != &other) {
            Base::operator=(other); // 显式调用基类赋值运算符
            derivedData = other.derivedData;
        }
        return *this;
    }
private:
    int derivedData;
};
  • 派生类的operator=会隐藏基类的operator=,因此必须通过Base::operator=(other)显式调用基类的赋值逻辑。

  • 若不调用,基类部分将不会被赋值,导致对象状态不一致。

  • 如果基类没有定义赋值运算符,编译器会自动生成一个浅拷贝的赋值运算

4.4析构函数 

1.派生类析构函数自动调用基类析构函数

派生类析构函数执行完毕后,会自动调用基类的析构函数,确保资源按 “派生类→基类” 的顺序释放。

class Base {
public:
    ~Base() { cout << "Base Destructor" << endl; }
};

class Derived : public Base {
public:
    ~Derived() { cout << "Derived Destructor" << endl; }
};

// 使用示例
int main() {
    Derived d; // 离开作用域时自动析构
    return 0;
}

  • 派生类对象销毁时,先执行自身的析构函数(清理派生类资源),再自动调用基类的析构函数(清理基类资源)。

  • 这种顺序确保资源释放的完整性,避免基类资源在派生类资源之前被释放。

 2.派生类对象析构顺序:派生类析构→基类析构
class Base {
public:
    ~Base() { cout << "Base Destructor" << endl; }
};

class Derived : public Base {
public:
    ~Derived() { cout << "Derived Destructor" << endl; }
};

// 使用示例
int main() {
    Derived* d = new Derived();
    delete d; // 显式释放对象
    return 0;
}

操作顺序 / 规则关键原因
构造函数基类构造 → 派生类构造派生类可能依赖基类初始化
拷贝构造函数显式调用基类拷贝构造确保基类部分被正确复制
赋值运算符 (operator=)显式调用基类operator=避免基类部分未被赋值
析构函数派生类析构 → 基类析构(自动调用)确保资源按正确顺序释放

4.5实现⼀个不能被继承的类 

⽅法1:基类的构造函数私有,派⽣类的构成必须调⽤基类的构造函数,但是基类的构成函数私有化以后,派⽣类看不⻅就不能调⽤了,那么派⽣类就⽆法实例化出对象。

⽅法2:C++11新增了⼀个final关键字,final修改基类,派⽣类就不能继承了。

class Base final
{
public:
    void func5() { cout << "Base::func5" << endl; }
protected:
    int a = 1;
private:
    // C++98的⽅法
    /*Base()
    {}*/
};
class Derive :public Base
{
    void func4() { cout << "Derive::func4" << endl; }
    protected:
    int b = 2;
};
int main()
{
    Base b;
    Derive d;
    return 0;
}

 5.继承和友元

友元关系不能继承,也就是说基类友元不能访问派⽣类私有和保护成员
简单来说, 友元(Friend) 就像你家的“特殊访客”,他们被允许进入你家客厅,访问私有和保护成员)。但这种权限 仅限于你家客厅(当前类),不会自动传递进入你的房间(派生类)。
#include <iostream>
using namespace std;

class Base {
private:
    int baseSecret = 10;  // 基类的私有成员
public:
    // 声明友元函数,允许访问基类的私有成员
    friend void visitBase(Base& b);
};

class Derived : public Base {
private:
    int derivedSecret = 20;  // 派生类的私有成员
};

// 基类的友元函数
void visitBase(Base& b) {
    cout << "访问基类的秘密: " << b.baseSecret << endl;  // 允许访问
    // cout << "尝试访问派生类的秘密: " << b.derivedSecret << endl;  // 错误!无法访问
}

int main() {
    Derived d;
    visitBase(d);  // 合法,但只能访问基类的成员
    return 0;
}

如果想让友元访问派生类对象,就需要将派生类中加入友元。

6.继承与静态成员

派生类和基类共用一份静态成员变量。

#include<iostream>
using namespace std;
class Person
{
public:
	string _name;
	static int _count;
};
int Person::_count = 0;
class Student : public Person
{
protected:
	int _stuNum;
};
int main()
{
	Person p;
	Student s;
	// 这⾥的运⾏结果可以看到⾮静态成员_name的地址是不⼀样的
	// 说明派⽣类继承下来了,⽗派⽣类对象各有⼀份
	cout << &p._name << endl;
	cout << &s._name << endl;
	// 这⾥的运⾏结果可以看到静态成员_count的地址是⼀样的
	// 说明派⽣类和基类共⽤同⼀份静态成员
	cout << &p._count << endl;
	cout << &s._count << endl;
	// 公有的情况下,⽗派⽣类指定类域都可以访问静态成员
	cout << Person::_count << endl;
	cout << Student::_count << endl;
	 return 0;
}

7. 多继承及其菱形继承问题

7.1继承模型

单继承:⼀个派⽣类只有⼀个直接基类时称这个继承关系为单继承
多继承:⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型是,先继承的基类在前⾯,后⾯继承的基类在后⾯,派⽣类成员在放到最后⾯。

产生问题

  • 数据冗余:公共基类成员在派生类中存在多份副本。

  • 二义性:访问公共成员时,编译器无法确定路径。

class Person
{
public:
	string _name; // 姓名
};
class Student : public Person
{
protected:
	int _num; //学号
};
class Teacher : public Person
{
protected:
	int _id; // 职⼯编号
};
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};
int main()
{
	// 编译报错:error C2385: 对“_name”的访问不明确
	Assistant a;
	a._name = "peter";
	// 需要显⽰指定访问哪个基类的成员可以解决⼆义性问题,但是数据冗余问题⽆法解决
	a.Student::_name = "xxx";
	a.Teacher::_name = "yyy";
	return 0;
}

 7.2虚继承

解决菱形继承(钻石继承)中的两个核心问题:数据冗余和二义性。

原理:通过虚继承,公共基类在最终派生类中仅保留一份实例。
  • Person成员只保留一份,通过虚基表指针访问。

#include <iostream>
using namespace std;

class Person {
public:
    string _name;
    Person(const string& name) : _name(name) {}
};

class Student : virtual public Person {  // 虚继承
public:
    Student(const string& name) : Person(name) {}
};

class Teacher : virtual public Person {  // 虚继承
public:
    Teacher(const string& name) : Person(name) {}
};

class TeachingAssistant : public Student, public Teacher {
public:
    // 最终派生类必须调用虚基类构造函数
    TeachingAssistant(const string& name) 
        : Person(name), Student(name), Teacher(name) {}
};

int main() {
    TeachingAssistant ta("Alice");
    cout << ta._name << endl;  // 直接访问,输出:Alice
    return 0;
}

不规则菱形在哪写virtual

7.3 小题

多继承中指针偏移问题?下⾯说法正确的是( )
A:p1 == p2 == p3 B:p1 < p2 < p3 C:p1 == p3 != p2 D:p1 != p2 != p3
class Base1 { public: int _b1; };
class Base2 { public: int _b2; };
class Derive : public Base1, public Base2 { public: int _d; };
int main()
{
	Derive d;
	Base1* p1 = &d;
	Base2* p2 = &d;
	Derive* p3 = &d;
	return 0;
}

其中 P1是继承的第一个基类,P2是继承的第二个基类,p1与p3的位置相同P2将往后移。

 7.4继承与组合

继承
  • 继承表示派生类是基类的一种特殊类型,即“是一个(is-a)”的关系。
    例如:狗是动物 → Dog 继承 Animal

  • 白箱复用:派生类可以直接访问基类的成员(包括保护成员),了解内部实现细节。

  • 高耦合:基类改动可能影响所有派生类,维护成本高。

  • 问题:继承破坏了基类的封装,鸡肋的 改变对派生类影响大,两者依赖性强,耦合度高。

class Animal {
public:
    void breathe() { cout << "呼吸中..." << endl; }
};

class Dog : public Animal {  // Dog is-a Animal
public:
    void bark() { cout << "汪汪!" << endl; }
};

int main() {
    Dog dog;
    dog.breathe();  // 继承自Animal
    dog.bark();
}
组合
  • 组合表示一个类包含另一个类的对象,即“有一个(has-a)”的关系。
    例如:汽车有发动机 → Car 包含 Engine

  • 黑箱复用:通过接口交互,无需了解内部实现。

  • 低耦合:被组合类的修改不会直接影响组合类。

class Engine {
public:
    void start() { cout << "引擎启动!" << endl; }
};

class Car {
private:
    Engine engine;  // Car has-a Engine
public:
    void drive() {
        engine.start();
        cout << "汽车行驶中..." << endl;
    }
};

int main() {
    Car car;
    car.drive();
}

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

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

相关文章

Linux grep -r 查找依赖包是否存在依赖类 Class

方法一&#xff1a;通过 Linux &#xff0c;grep -r ClassPath 命令 grep -f org.apache.kafka.connect.source.SourceRecord在 jar 包所在 lib 或者 lib/plugins 目录下执行&#xff0c;grep -r&#xff0c; flink-sql-connector-sqlserver-cdc-3.3.0.jar 中此 kafka Source…

41:像素坐标与实际坐标转化

采用上面的算子 将像素坐标点转换为实际坐标 image_points_to_world_plane(CamParam, Worldpose, Row, Column, m, X, Y) 第一个参数&#xff1a;标定得到的内参--根据标定助手得到的 第二个参数&#xff1a;标定得到的外参--根据标定助手得到的 第三个参数&#xff1a;计算…

大某麦演唱会门票如何自动抢

引言 仅供学习研究&#xff0c;欢迎交流 抢票难&#xff0c;难于上青天&#xff01;无论是演唱会、话剧还是体育赛事&#xff0c;大麦网的票总是秒光。大麦网是国内知名的票务平台&#xff0c;热门演出票往往一票难求。手动抢票不仅耗时&#xff0c;还容易错过机会。作为一名…

LVS负载均衡群集和keepalive

目录 一. 集群概述 1.1 集群的定义 1.2 集群的分类 1. 高可用集群 HA 2. 高性能运输群集 HPC 3.负载均衡群集 LB 4. 分布式存储集群 二. LVS概述 2.1 LVS的定义 2.2 LVS的工作原理 2.3 LVS 的三种工作模式 2.4 LVS 三种工作模式的对比 2.5 LVS 调度算法 1. 静态…

Apache Pulsar 消息、流、存储的融合

Apache Pulsar 消息、流、存储的融合 消息队列在大层面有两种不同类型的应用&#xff0c;一种是在线系统的message queue&#xff0c;一种是流计算&#xff0c;data pipeline的streaming高throughout&#xff0c;一致性较低&#xff0c;延迟较差的过程。 存算分离 扩容和缩容快…

最优化方法Python计算:有约束优化应用——线性可分问题支持向量机

设问题的数据样本点 ( x i , y i ) (\boldsymbol{x}_i,y_i) (xi​,yi​)&#xff0c; x i ∈ R n \boldsymbol{x}_i\in\text{R}^n xi​∈Rn&#xff0c; y i 1 y_i\pm1 yi​1&#xff0c; i 1 , 2 , ⋯ , m i1,2,\cdots,m i1,2,⋯,m。由于标签数据 y i ∈ { − 1 , 1 } y_i\…

SpringBoot学习(上) , SpringBoot项目的创建(IDEA2024版本)

目录 1. SpringBoot介绍 SpringBoot特点 2. SpringBoot入门 2.1 创建SpringBoot项目 Spring Initialize 第一步: 选择创建项目 第二步: 选择起步依赖 第三步: 查看启动类 2.2 springboot父项目 2.3 测试案例 2.3.1 数据库 2.3.2 生成代码 1. SpringBoot介绍 Spring B…

【Redis 进阶】哨兵模式

思维导图&#xff1a; 一、哨兵模式概述 &#xff08;一&#xff09;传统主从复制模式的局限性 在传统的Redis主从复制架构中&#xff0c;若主节点发生故障&#xff0c;运维人员需手动执行故障转移操作&#xff0c;将一个从节点提升为新主节点&#xff0c;并逐一通知所有客户…

CVE-2025-31258 macOS远程视图服务沙箱逃逸漏洞PoC已公开

苹果公司近日针对macOS系统中新披露的CVE-2025-31258漏洞发布补丁&#xff0c;该漏洞可能允许恶意应用程序突破沙箱限制&#xff0c;获取未授权的系统资源访问权限。在安全研究员Seo Hyun-gyu公开概念验证&#xff08;PoC&#xff09;利用代码后&#xff0c;该漏洞已在macOS Se…

武汉大学无人机视角下的多目标指代理解新基准!RefDrone:无人机场景指代表达理解数据集

作者&#xff1a;Zhichao Sun, Yepeng Liu, Huachao Zhu, Yuliang Gu, Yuda Zou, Zelong Liu, Gui-Song Xia, Bo Du, Yongchao Xu 单位&#xff1a;武汉大学计算机学院 论文标题&#xff1a;RefDrone: A Challenging Benchmark for Drone Scene Referring Expression Compreh…

【递归、搜索和回溯】二叉树中的深搜

个人主页 &#xff1a; zxctscl 专栏 【C】、 【C语言】、 【Linux】、 【数据结构】、 【算法】 如有转载请先通知 文章目录 前言1 2331. 计算布尔二叉树的值1.1 分析1.2 代码 2 129. 求根节点到叶节点数字之和2.1 分析2.2 代码 3 814. 二叉树剪枝3.1 分析3.2 代码 4 98. 验证…

Algolia - Docsearch的申请配置安装【以踩坑解决版】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

Linux513 rsync本地传输 跨设备传输 一

ping节点bPing通 仅主机模式不需要设置网关节点a也可以Ping通节点b 同步成功 下载文件夹成功 今日源码 节点a 节点b

leetcode 383. Ransom Note

题目描述 代码 class Solution { public:bool canConstruct(string ransomNote, string magazine) {vector<int> table(26,0);for(char ch : magazine){table[ch-a];}for(char ch : ransomNote){table[ch-a]--;if(table[ch-a] < 0)return false;}return true;} };

Skyvern:用 AI+视觉驱动浏览器自动化

Skyvern&#xff1a;用 AI视觉驱动浏览器自动化 一、前言二、项目概览2.1 Skyvern 项目简介2.2 代码结构与模块划分 三、环境搭建与快速上手3.1 环境准备3.1.1 系统与依赖3.1.2 克隆项目3.1.3 安装 Python 依赖3.1.4 配置环境变量3.1.5 启动服务 3.2 验证安装 四、核心功能与实…

数据库原理期末考试速成--最后附带两套题

引言 为什么从3开始呢,毕竟是速成吗,总要放弃一些东西 前两章1.概论 2.关系数据库:这里面都是一些运算符什么的,我感觉都学这个:笛卡尔积之列的都会算 这两章比较重要的我就放在这里了 选择、投影、连接、除、并、交、差,其中选择、投影、并、差、笛卡尔积是5种基本关…

数据结构基础--蓝桥杯备考

1.优缺点总述 STL中各容器对比图 各类线性数据结构优缺点 1.数组 1.优点 1.简单&#xff0c;容易理解 2.访问快捷&#xff0c;只需要用下标就可以 3.有某些应用场景直接对应&#xff0c;例如二维数组对应平面 2.缺点 删除和插入数据非常耗时 2.链表 1.优点 插入和删…

2.4GHz无线通信芯片选型指南:集成SOC与低功耗方案解析

今天给大家分享几款2.4GHz无线通信芯片方案&#xff1a; 一、集成SOC芯片方案 XL2407P&#xff08;芯岭技术&#xff09; 集成射频收发机和微控制器&#xff08;如九齐NY8A054E&#xff09; 支持一对多组网和自动重传 发射功率8dBm&#xff0c;接收灵敏度-96.5dBm&#xff08…

Unity_JK框架【5】音效系统实现

在游戏开发中&#xff0c;音频是不可或缺的一部分&#xff0c;它能够极大地增强游戏的沉浸感和趣味性。今天&#xff0c;我们就用JK框架 探讨一下如何在Unity中实现一个强大的音频系统&#xff0c;并且通过实际的测试脚本来验证其功能&#x1f44f;。 一、音频模块类&#xff1…

鸿蒙 从打开一个新窗口到Stage模型的UIAbility组件

打开一个新的窗口 我们首先来实现如何在一个应用中打开一个新窗口&#xff0c;使用的模型是 Stage 模型 在项目文件里&#xff0c;新建一个 newWindow.ets 新文件 src/main/ets/pages/newWindow.ets newWindow.ets文件里面随便写点什么都行&#xff0c;这里是第一步创建的文件…