[C++]类的继承

一、什么是继承

1.定义

        在 C++ 中,继承是一种机制,允许一个类(派生类)继承另一个类(基类)的成员(数据和函数)。继承使得派生类能够直接访问基类的公有和保护成员,同时也可以对这些成员进行扩展或修改。继承是一种“是一个”的关系,它允许一个类从另一个类继承其属性和方法,从而实现代码的复用。派生类是基类的一种特殊类型。

如何理解“是一个”?

如"狗是动物","猫是动物",Cat,Dog这两个类都继承了Animal这个类,它们是属于的关系,是“是一个”的关系。

2.继承的作用

        继承的主要作用是实现代码的复用:派生类可以重用基类的代码,而不需要重复编写相同的功能。同时,继承也允许派生类扩展或修改基类的行为。


二、基类与派生类

1.基类

        定义通用功能的类,供其他类继承。

2.派生类

        从基类继承的类,可以继承、扩展或修改基类的功能。

3.简单示例

        用一个简单的动物类和狗类示例,展示基类和派生类的关系。

#include <iostream>
using namespace std;// 基类:动物
class Animal {
public:void eat() { cout << "Animal is eating" << endl; }
};// 派生类:狗(继承了动物的功能)
class Dog : public Animal {
public:void bark() { cout << "Dog is barking" << endl; }
};int main() {Dog dog;dog.eat(); // 狗继承了动物的吃饭功能dog.bark(); // 狗有自己的叫的功能return 0;
}

三、继承的访问控制

1.公有继承

        当派生类以 public 方式继承基类时,基类的公有成员和保护成员在派生类中保持原有的访问权限,而私有成员完全不可访问。

1.公有成员(public):可以通过派生类对象访问。

2.保护成员(protected):可以在派生类内部访问,但不能通过派生类对象直接访问。

3.私有成员(private):完全无法访问。

4.示例:

#include <iostream>
using namespace std;class Animal {
public:void eat() { cout << "Animal eats." << endl; }  // 公有成员
protected:void sleep() { cout << "Animal sleeps." << endl; }  // 保护成员
private:void walk() { cout << "Animal walks." << endl; }  // 私有成员
};class Dog : public Animal {  // 公有继承
public:void dogActions() {eat();   // 可以访问公有成员sleep(); // 可以访问保护成员// walk(); // 错误,不能访问私有成员}
};int main() {Dog d;d.dogActions();return 0;
}
/*输出:
Animal eats.
Animal sleeps.
*/
1.解释:
  • 由于继承方式是 publicDog 类可以访问基类 Animal 的公有成员 eat() 和保护成员 sleep()
  • 但是,Dog 类不能访问基类 Animal 的私有成员 walk()

2.保护继承

        当派生类以 protected 方式继承基类时,基类的公有成员和保护成员都变成保护成员,只能在派生类及其子类中访问,不能通过派生类对象直接访问。

1.公有成员(public)变为保护成员(protected)。

2.保护成员(protected)仍然是保护成员。

3.私有成员(private)完全不可访问。

4.示例:

#include <iostream>
using namespace std;class Animal {
public:void eat() { cout << "Animal eats." << endl; }  // 公有成员
protected:void sleep() { cout << "Animal sleeps." << endl; }  // 保护成员
private:void walk() { cout << "Animal walks." << endl; }  // 私有成员
};class Dog : protected Animal {  // 保护继承
public:void dogActions() {eat();   // 可以访问保护成员sleep(); // 可以访问保护成员// walk(); // 错误,不能访问私有成员}
};int main() {Dog d;d.dogActions();// d.eat(); // 错误,不能通过对象访问 public 成员return 0;
}
/*输出:
Animal eats.
Animal sleeps.
*/
1.解释:
  • 由于继承方式是 protectedDog 类可以访问基类 Animal 的公有成员 eat() 和保护成员 sleep(),但是这些成员不能通过派生类对象直接访问。
  • Dog 类不能访问 Animal 类的私有成员 walk()

3.私有继承

        当派生类以 private 方式继承基类时,基类的公有成员和保护成员都变成私有成员,只能在派生类内部访问,不能通过派生类对象访问。

1.公有成员(public)变为私有成员(private)。

2.保护成员(protected)变为私有成员(private)。

3.私有成员(private)仍然不可访问。

4.示例:

#include <iostream>
using namespace std;class Animal {
public:void eat() { cout << "Animal eats." << endl; }  // 公有成员
protected:void sleep() { cout << "Animal sleeps." << endl; }  // 保护成员
private:void walk() { cout << "Animal walks." << endl; }  // 私有成员
};class Dog : private Animal {  // 私有继承
public:void dogActions() {eat();   // 可以访问私有成员(但只能在类内部访问)sleep(); // 可以访问保护成员(但只能在类内部访问)// walk(); // 错误,不能访问私有成员}
};int main() {Dog d;d.dogActions();//通过派生类的成员函数访问基类的成员函数// d.eat(); // 错误,不能通过对象访问 private 成员return 0;
}
/*输出:
Animal eats.
Animal sleeps.
*/
1.解释:
  • 由于继承方式是 privateDog 类可以访问基类 Animal 的公有成员 eat() 和保护成员 sleep(),但是这些成员都变成了 private,所以不能通过派生类对象直接访问。
  • 由于 eat()sleep()Dog 类的成员函数中被调用,它们可以访问 Animal 类的公有成员和保护成员。
  • 但是,如果尝试从 Dog 类的对象外部调用 eat()sleep()(如 d.eat()d.sleep()),就会报错,因为它们被转换成了私有或保护成员,不能通过外部代码直接访问。但因为Dog类的dogActions()方法是对外公开的,而这个dogActions()方法可以访问到基类的eat()和sleep()方法,因此可以通过Dog类的公有成员方法间接访问到基类的eat和sleep方法。
  • 类外Dog 类不能访问 Animal 类的私有成员 walk()

4. 总结继承的访问控制

继承方式基类 public 成员基类 protected 成员基类 private 成员
public保持 public保持 protected不能访问
protected变为 protected变为 protected不能访问
private变为 private变为 private不能访问

四、 抽象类与纯虚函数

  • 抽象类:一个不能直接实例化的类,通常包含纯虚函数。
  • 纯虚函数:没有实现的函数,要求派生类实现。
  • 示例:展示如何定义抽象类,并解释其在接口设计中的应用。
    class Animal {
    public:virtual void sound() = 0;  // 纯虚函数
    };class Dog : public Animal {
    public:void sound() override { std::cout << "Bark" << std::endl; }
    };
    

关于抽象类与纯虚函数我的这篇笔记里有详细讲,大家可以转站这里


五、多级继承与多重继承

1.多级继承

1. 定义

多级继承是指类的继承关系形成一个层次结构(是逐级进行的,类与类之间有明确的层级关系,每一层只能继承一个父类),其中派生类不仅继承了基类的成员,还继承了另外一个派生类的成员。

具体来说,就是:

  1. 基类(祖父类):最顶层的类。
  2. 派生类(父类):继承自基类的类。
  3. 子类(孙子类):继承自派生类(父类)的类。

在这种情况下,子类(孙子类)不仅继承了派生类(父类)的成员,还间接继承了基类(祖父类)的成员。子孙类的继承就叫多级继承。

例如:

#include<iostream>
using namespace std;class A {  // 基类
public:void showA() { cout << "Class A" << endl; }
};class B : public A {  // 派生类 B 继承自 A
public:void showB() { cout << "Class B" << endl; }
};class C : public B {  // 子类 C 继承自 B(间接继承自 A)
public:void showC() { cout << "Class C" << endl; }
};int main() {C obj;obj.showA();  // 通过 C 访问 A(通过继承的方式)obj.showB();  // 通过 C 访问 Bobj.showC();  // 通过 C 访问 Creturn 0;
}/*输出Class AClass BClass C
*/

在这个例子中:

  • A 是基类。
  • B 是派生类,它直接继承自 A
  • C 是子类,它继承自 B,但间接继承了 A 的成员。
  • C 类继承自 B 类,B 类又继承自 A 类。因此,C 类间接继承了 A 类的成员,这就是“继承链条中,派生类继续继承另一个派生类,形成一个层次结构”。
  • 子类(如 C)不仅可以访问直接继承的父类(如 B)的成员,还可以访问间接继承的祖父类(如 A)的成员。

2. 特性

  • 在多级继承中,继承链条从基类开始,一层一层向下继承。
  • 子类可以直接访问祖先类的公有成员,但需要注意继承的访问权限。例如,C 类可以通过继承链访问 A 类的公有成员。

3. 访问控制

  • 基类成员的访问控制(公有、保护、私有)会影响到继承链条中的派生类对基类成员的访问。
  • 在多级继承中,派生类不仅能访问自己类的成员,还能访问祖先类的公有成员和保护成员。

2.多重继承

1. 定义

多重继承是指一个类可以同时继承多个基类。也就是说,派生类可以同时继承多个父类的成员,具有多个基类。这是 C++ 允许的继承方式。例如:

class A {
public:void showA() { cout << "Class A" << endl; }
};class B {
public:void showB() { cout << "Class B" << endl; }
};class C : public A, public B {  // C 同时继承 A 和 B
public:void showC() { cout << "Class C" << endl; }
};

在这个例子中:

  • C 类继承了 A 类和 B 类,意味着 C 类将拥有 AB 类的成员。、

2. 特性

  • 派生类可以有多个直接的父类。
  • 每个父类的成员都可以被派生类访问。
  • 可能会发生命名冲突,如果多个父类有同名的成员,派生类需要通过作用域解析符来明确指定使用哪个父类的成员。
  • 如果两个基类有相同的成员,可能会出现钻石问题,但可以通过虚拟继承解决。

3. 访问控制

  • 和多级继承类似,多重继承中基类成员的访问控制(公有、保护、私有)依然适用。
  • 如果两个基类有同名的成员(钻石问题),在派生类中需要通过作用域解析符来区分它们。

4. 实例

#include <iostream>
using namespace std;class A {
public:void showA() { cout << "Class A" << endl; }
};class B {
public:void showB() { cout << "Class B" << endl; }
};class C : public A, public B {
public:void showC() { cout << "Class C" << endl; }
};int main() {C obj;obj.showA();  // 通过 C 访问 Aobj.showB();  // 通过 C 访问 Bobj.showC();  // 通过 C 访问 Creturn 0;
}
//输出:Class A Class B Class C

在这个例子中,C 类继承了 AB 两个类,所以它可以直接访问 AB 的公有成员。

5. 潜在的问题(如钻石问题)

多重继承可能导致一些潜在问题,最典型的就是 钻石问题。例如,如果两个基类有相同的成员,派生类可能无法明确继承哪个成员。C++ 通过 虚拟继承 来解决这个问题。

1.钻石问题的例子
#include <iostream>
using namespace std;class A {
public:void showA() { cout << "Class A" << endl; }
};class B : public A {
public:void showB() { cout << "Class B" << endl; }
};class C : public A {
public:void showC() { cout << "Class C" << endl; }
};class D : public B, public C {  // D 同时继承 B 和 C
public:void showD() { cout << "Class D" << endl; }
};int main() {D obj;obj.showA();  // 错误:不明确的继承(钻石问题)return 0;
}

在这个例子中,D 类继承了 BC,而 BC 都继承了 A 类。这样,D 类有两个 A 类的副本,因此不明确的继承会导致编译错误。

2.解决钻石问题:虚拟继承

通过使用虚拟继承(virtual 关键字),C++ 会确保基类 A 只有一个副本。

class A {
public:void showA() { cout << "Class A" << endl; }
};class B : virtual public A {
public:void showB() { cout << "Class B" << endl; }
};class C : virtual public A {
public:void showC() { cout << "Class C" << endl; }
};class D : public B, public C {
public:void showD() { cout << "Class D" << endl; }
};int main() {D obj;obj.showA();  // 现在可以访问 A,因为 A 只有一个副本return 0;
}
//输出:Class A

3.总结

1. 多级继承

  • 一种继承方式,子类继承父类,父类又继承祖父类,形成继承链条。
  • 子类能够访问基类和祖父类的成员(根据访问权限)。

2. 多重继承

  • 一个子类可以继承多个父类。
  • 如果多个父类有同名成员,可能会导致命名冲突(钻石问题),需要使用作用域解析符来明确调用。
  • 可以通过虚拟继承来避免钻石问题。
特性多级继承多重继承
继承关系逐级的,类与类之间形成一个明确的层级关系类同时继承多个父类,父类之间不一定有层级关系
父类数量每一层只有一个父类一个派生类可以有多个直接的父类
结构继承链是单向的,层次化的继承关系是并列的,可以有多个父类
命名冲突不容易发生命名冲突如果父类有相同成员,可能会发生命名冲突
例子class C : public B { ... }class B : public A { ... }class C : public A, public B { ... }

六、虚函数与多态

  • 虚函数:基类中的函数被声明为虚函数时,派生类可以重写该函数,实现运行时多态。
  • 多态:解释静态多态和动态多态的区别。
  • 示例:展示虚函数如何实现动态绑定,通过基类指针或引用调用派生类的函数。
    class Animal {
    public:virtual void sound() { std::cout << "Animal makes a sound" << std::endl; }
    };class Dog : public Animal {
    public:void sound() override { std::cout << "Dog barks" << std::endl; }
    };int main() {Animal* animal = new Dog();animal->sound();  // 动态绑定,调用 Dog 类中的 sound()delete animal;return 0;
    }
    

虚函数的详细笔记 

多态的详细笔记


七、继承中的构造函数与析构函数

1. 构造函数的继承行为

基本规则:
  • 派生类的构造函数会调用基类的构造函数。这意味着在派生类的构造函数中,基类的构造函数会先被调用,然后才会执行派生类的构造代码。
  • 基类的构造函数被自动调用,即使你没有显式调用它。默认情况下,如果基类有无参构造函数,那么它会在派生类构造函数中自动调用。
  • 如果基类有带参构造函数,派生类必须显式调用基类的构造函数(使用初始化列表)。
示例:构造函数继承行为
#include <iostream>
using namespace std;class Base {
public:Base() {  // 无参构造函数cout << "Base class constructor" << endl;}Base(int x) {  // 带参构造函数cout << "Base class constructor with value: " << x << endl;}
};class Derived : public Base {
public:Derived() : Base(10) {  // 显式调用基类的构造函数cout << "Derived class constructor" << endl;}
};int main() {Derived d;  // 创建派生类对象return 0;
}/*输出:
Base class constructor with value: 10
Derived class constructor*/

解释:

  • 当创建派生类对象 d 时,首先会调用基类 Base 的构造函数(带参构造函数 Base(int x)),并传入参数 10,然后才会执行派生类的构造函数。

2. 析构函数的继承行为

基本规则:
  • 派生类的析构函数会先执行。当对象销毁时,析构的顺序是:首先调用派生类的析构函数,然后再调用基类的析构函数。
  • 基类的析构函数应该是虚拟的:
    • 这是为了确保正确地析构派生类对象,避免资源泄漏。当你有一个基类和一个派生类,并且你通过基类指针去删除派生类对象时,如果基类的析构函数不是虚拟的,那么在删除对象时,程序就只会执行基类的析构函数派生类的析构函数就不会执行
    • 这种情况下,派生类对象在销毁时可能会留下未释放的资源(比如动态分配的内存、打开的文件或其他重要的资源),导致资源泄漏,即这些资源被占用但没有被正确释放。
    • 而如果基类的析构函数是虚拟的,程序就知道在删除派生类对象时,先执行派生类的析构函数,释放派生类分配的资源,然后再执行基类的析构函数,释放基类的资源。这样就能确保资源得到完全释放,避免浪费
示例:析构函数继承行为
#include <iostream>
using namespace std;class Base {
public:Base() {cout << "Base class constructor" << endl;}~Base() {  // 基类的析构函数cout << "Base class destructor" << endl;}
};class Derived : public Base {
public:Derived() {cout << "Derived class constructor" << endl;}~Derived() {  // 派生类的析构函数cout << "Derived class destructor" << endl;}
};int main() {Derived d;  // 创建派生类对象return 0;
}/*输出
Base class constructor
Derived class constructor
Derived class destructor
Base class destructor
*/

解释:

  • 创建对象 d 时,首先调用基类的构造函数,然后调用派生类的构造函数。
  • d 被销毁时,先调用派生类的析构函数,再调用基类的析构函数。
虚拟析构函数

在多态情况下,派生类对象是通过基类指针删除的,这时必须将基类的析构函数声明为虚拟的,以确保派生类的析构函数得到调用。否则,可能会导致资源泄漏。

#include <iostream>
using namespace std;class Base {
public:virtual ~Base() {  // 基类的虚拟析构函数cout << "Base class destructor" << endl;}
};class Derived : public Base {
public:~Derived() {  // 派生类的析构函数cout << "Derived class destructor" << endl;}
};int main() {Base* b = new Derived();  // 基类指针指向派生类对象delete b;  // 通过基类指针删除派生类对象return 0;
}/*
Derived class destructor
Base class destructor
*/

解释:

  • delete b 时,基类的虚拟析构函数确保先调用派生类的析构函数,然后再调用基类的析构函数。否则,如果基类的析构函数没有声明为虚拟的,就只会调用基类的析构函数,导致派生类的析构函数没有执行,可能造成资源泄漏。

八、继承与组合的比较

1.组合

1.定义:

组合是表示类之间**“有一个(has-a)”**关系的机制。它通过将一个类的对象作为另一个类的成员来实现功能复用。

2.特点:

  • 组合实现了类与类之间的松散耦合关系。
  • 被组合的对象可以是其他类的实例。

3.组合与继承的区别:

  • 继承:适用于表示 "是一个" 关系的情况。
  • 组合:适用于表示 "有一个" 关系的情况。类之间通过成员对象组合实现功能。

4.示例

#include <iostream>
using namespace std;class Leg {
public:void walk() {cout << "腿在跑。" << endl;}
};class Dog {
private:Leg leg;  // Dog 有一个 Leg
public:void walk() {leg.walk();  // 通过组合对象调用其功能}
};int main() {Dog dog;dog.walk(); // 调用组合对象的方法return 0;
}

2.继承 vs 组合:如何选择?

1.组合与继承的对比

方面继承组合
关系类型是一个(is-a)有一个(has-a)
耦合程度紧密耦合松散耦合
灵活性低(子类依赖父类)高(可以动态修改组合关系)
代码复用子类复用父类代码通过组合成员实现功能复用
使用场景表示类之间是一种“类型”的关系,如动物与狗表示类之间有一个成员的关系,如狗与腿

2. 综合示例

下面是继承和组合的综合使用示例,展示它们的区别和使用场景:

#include <iostream>
using namespace std;// 父类:动物
class Animal {
public:void eat() {cout << "Animal is eating." << endl;}
};// 组合类:腿
class Leg {
public:void walk() {cout << "Leg is walking." << endl;}
};// 子类:狗
class Dog : public Animal { // 继承:狗是动物
private:Leg leg; // 组合:狗有一个腿
public:void walk() {leg.walk(); // 使用组合对象的功能}void bark() {cout << "Dog barks!" << endl;}
};int main() {Dog dog;dog.eat();  // 继承自 Animaldog.walk(); // 组合的功能dog.bark(); // Dog 类的独特功能return 0;
}

3.最后:

  • 在设计复杂系统时,应尽量优先使用组合而非继承,因为组合更加灵活并且降低了类之间的耦合性。
  • 如果需要扩展父类的功能或表示一种“类型”的关系,则继承是合理的选择。

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

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

相关文章

harbor镜像仓库搭建

Harbor简介 Harbor的发展背景和现状 Harbor项目起始于2014年左右,当时正值容器技术和微服务架构迅速崛起的时期。随着越来越多的企业开始采用容器化部署应用,对于私有镜像管理的需求也日益增长。传统的解决方案要么缺乏必要的企业级特性(如访问控制、安全性和可扩展性),…

01-51单片机硬件基础

开发板介绍 学校授课用的是普中科技的EM3.V2.2开发板&#xff0c;没什么好说的&#xff0c;记着去淘宝上找原理图&#xff0c;别迷信课本。 网上有卖51最小系统板的&#xff0c;比开发板便宜&#xff0c;也有下载模块&#xff0c;可以自己搭建外围电路。 还可以自己在protue…

方法引用和lambda表达式的奥妙

方法引用替代Lambda表达式 什么情况可以使用方法引用替代lambda表达式&#xff1f; 下面代码中两处使用了lambda表达式&#xff0c;一个是filter内&#xff0c;一个是forEach内。其中&#xff0c;forEach内的lambda表达式可以被方法引用替代&#xff0c;但是filter内的lambda…

Android通过okhttp下载文件(本文案例 下载mp4到本地,并更新到相册)

使用步骤分为两步 第一步导入 okhttp3 依赖 第二步调用本文提供的 utils 第一步这里不做说明了&#xff0c;直接提供第二步复制即用 DownloadUtil 中 download 为下载文件 参数说明 这里主要看你把 destFileName 下载文件名称定义为什么后缀&#xff0c;比如我定义为 .mp4 下…

What is load balancing? 什么是负载均衡?

原文链接 What Is Load Balancing? | IBM 什么是负载均衡&#xff1f; 在多台服务器之间高效的分配网络流量的过程&#xff0c;以优化应用程序的可用性&#xff0c;同时确保积极的用户体验。 电商网站依赖负载均衡&#xff08;load balancing&#xff09;来确保web应用能够无…

黑马商城微服务复习(6)

MQ高级 1. 消息可靠性2. 发送者的可靠性1. 发送者问题2. 生产者重试机制3. 生产者确认机制4. MQ可靠性5. 消费者的可靠性 3. 延迟消息1. 定义2. 死信交换机 1. 消息可靠性 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生产者发…

内网是如何访问到互联网的(华为源NAT)

私网地址如何能够访问到公网的&#xff1f; 在上一篇中&#xff0c;我们用任意一个内网的终端都能访问到百度的服务器&#xff0c;但是这是我们在互联网设备上面做了回程路由才实现的&#xff0c;在实际中&#xff0c;之前也说过运营商是不会写任何路由过来的&#xff0c;那对于…

oracle归档模式下的快速热备方法-适合小库

在我们的一些小型的oracle生产库中&#xff0c;有些时候我们可以在不停库且不使用rman的情况下实现数据库的热备。该热备的原理是通过控制数据文件块头的scn号在备份时候不变化&#xff0c;进而保证备份的数据文件数据一致性。 一、环境 数据库版本&#xff1a; 数据库需要开启…

rabbitMq举例

新来个技术总监&#xff0c;把 RabbitMQ 讲的那叫一个透彻&#xff0c;佩服&#xff01; 生产者 代码举例 public String sendMsg(final String exchangeName,final String routingKey,final String msg) {} /*** 发送消息* param exchangeName exchangeName* param routin…

2024年12月13日Github流行趋势

项目名称&#xff1a;nexus-xyz / nexus-zkvm 项目维护者&#xff1a;govereau slumber danielmarinq sjudson yoichi-nexus项目介绍&#xff1a;Nexus zkVM 是一个零知识虚拟机。项目star数&#xff1a;1,948项目fork数&#xff1a;343 项目名称&#xff1a;soxoj / maigret …

(九)机器学习 - 多项式回归

多项式回归&#xff08;Polynomial Regression&#xff09;是一种回归分析方法&#xff0c;它将自变量 xx 和因变量 yy 之间的关系建模为 nn 次多项式。多项式回归的目的是找到一个 nn 次多项式函数&#xff0c;使得这个函数能够最好地拟合给定的数据点。 多项式回归的数学表达…

Linux USB开发整理和随笔

目录 1 概述 2 硬件原理基础 2.1 USB发展 2.2 USB的拓扑 2.3 硬件接口 2.4 USB总线协议 2.4.1 通信过程 2.4.2 概念关系 2.4.3 管道PIPE 2.4.4 传输 2.4.5 事务 2.4.6 包结构与类型 2.4.6.1 令牌包 2.4.6.2 数据包 2.4.6.3 握手包 2.5 描述符 2.5.1 设备描述符…

️️️ 避坑指南:如何修复国密gmssl 库填充问题并提炼优秀加密实践20241212

&#x1f6e1;️ 避坑指南&#xff1a;如何修复国密gmssl 库填充问题并提炼优秀加密实践 ✨ 引言 在当下的数据安全环境中&#xff0c;SM4作为中国国家密码算法的代表性选择&#xff0c;被广泛应用于金融、通信和政府领域。然而&#xff0c;在实际开发中&#xff0c;即便是开…

沈阳理工大学《2024年811自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《沈阳理工大学811自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2024年真题 Part1&#xff1a;2024年完整版真题 2024年真题

2023 年 408 大题解析

讲解视频推荐&#xff1a; 【BOK408真题讲解-2023】 一、数据结构 1. 算法题&#xff08;图的邻接矩阵&#xff09;13’ 已知有向图 G 采用邻接矩阵存储&#xff0c;类型定义如下&#xff1a; typedef struct{ //图的类型定义int num Vertices, numEdges; //图的顶点数和有…

【R语言】基础知识

一、对象与变量 R语言中的所有事物都是对象&#xff0c;如向量、列表、函数&#xff0c;变量、甚至环境等。它的所有代码都是基于对象object的操作&#xff0c;变量只是调用对象的手段。 1、对象 在R语言中&#xff0c;对计算机内存的访问是通过对象实现的。 # 字符型向量 …

【SpringBug】lombok插件中@Data不能生成get和set方法

一&#xff1a;问题引入 可以看到我们在类UserInfo上写了Data注解&#xff0c;但是在测试文件中生成的反编译target文件Us二Info中没有get和set方法 二&#xff1a;解决方法 1&#xff1a;Spring升级问题&#xff08;解决了我的问题&#xff09; 原因是Spring官方进行了升级…

Java版-图论-最短路-Floyd算法

实现描述 网络延迟时间示例 根据上面提示&#xff0c;可以计算出&#xff0c;最大有100个点&#xff0c;最大耗时为100*wi,即最大的耗时为10000&#xff0c;任何耗时计算出来超过这个值可以理解为不可达了&#xff1b;从而得出实现代码里面的&#xff1a; int maxTime 10005…

STM32 CubeMx HAL库 独立看门狗IWDG配置使用

看门狗这里我就不多介绍了&#xff0c;能搜到这篇文章说明你了解 总之就是一个单片机重启程序&#xff0c;设定好超时时间&#xff0c;在超时时间内没有喂狗&#xff0c;单片机就会复位 主要应用在单片机异常重启方面&#xff0c;比如程序跑飞&#xff08;注意程序跑飞时你就…

uni-app实现小程序、H5图片轮播预览、双指缩放、双击放大、单击还原、滑动切换功能

前言 这次的标题有点长&#xff0c;主要是想要表述的功能点有点多&#xff1b; 简单做一下需求描述 产品要求在商品详情页的头部轮播图部分&#xff0c;可以单击预览大图&#xff0c;同时在预览界面可以双指放大缩小图片并且可以移动查看图片&#xff0c;双击放大&#xff0…