C++1进阶(继承)

使用安卓的IMU数据进行 行人航位推算(PDR)推算步长 附python 代码 加速度计数据、陀螺仪数据、重力传感器数据、姿态仰角数据。数据分析与定位轨迹生成主要使用Python离线完成。示意图。 阅读详情

C++ 继承从入门到吃透
目录

1.唠唠继承是个啥 —— 概念 + 定义
2.基类派生类的 “赋值小规则”—— 对象转换那些事
3.继承里的 “地盘之争”—— 作用域问题
4.派生类的 “六大默认成员函数”—— 编译器帮我们做了啥
5.友元和静态成员的 “继承小脾气”—— 能继承吗?咋用?
6.继承里的 “大坑”—— 菱形继承与虚拟继承
7.继承的 “灵魂反思”—— 咋用才对?继承 vs 组合
8.笔试面试高频题 —— 考点速记

作为一名 C++ 初学者,刚接触继承的时候总觉得它又绕又复杂,光是基类、派生类、访问限定符这些概念就记了好久,更别说菱形继承、虚拟继承这些 “进阶坑” 了。但学懂之后才发现,继承其实是 C++ 实现代码复用的核心手段,相当于站在已有类的基础上 “搭积木”,不用再重复写相同的代码,这对后续写大型程序太重要了。

1. 唠唠继承是个啥 —— 概念 + 定义
1.1 继承的核心概念
继承(inheritance)是 C++ 面向对象编程中类层次的代码复用手段(之前我们接触的都是函数复用,比如写个函数反复调用)。简单来说:在原有类的基础上,增加新功能、扩展特性,生成的新类就是派生类(子类),原有类就是基类(父类)。
继承体现了 “由简单到复杂” 的认知逻辑,比如生活中 “人” 是基础类,有姓名、年龄等属性;“学生” 和 “老师” 都是人的子类,在人的基础上,分别增加了学号、工号等专属属性,这就是继承的思想。

小例子(直观感受复用):

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

// 基类:人
class Person
{
public:
    void Print()
    {
        cout << "name:" << _name << endl;
        cout << "age:" << _age << endl;
    }
protected:
    string _name = "peter"; // 姓名
    int _age = 18; // 年龄
};

// 派生类:学生,public继承自Person
class Student : public Person
{
protected:
    int _stuid; // 学号(学生专属属性)
};

// 派生类:老师,public继承自Person
class Teacher : public Person
{
protected:
    int _jobid; // 工号(老师专属属性)
};

int main()
{
    Student s;
    Teacher t;
    // 直接复用基类的Print函数,不用重新写!
    s.Print();
    t.Print();
    return 0;
}

运行后会发现,Student 和 Teacher 对象能直接调用 Person 的 Print 函数,这就是继承的代码复用体现 —— 父类的成员(函数 + 变量)都会成为子类的一部分。

1.2 继承的定义格式与访问规则
(1)基本定义格式

派生类和基类的关系定义很固定,记住这个格式就行:

class 派生类名 : 继承方式 基类名
{
    // 派生类的成员(属性+函数)
};

比如class Student : public Person,其中public就是继承方式。

(2)3 种继承方式 + 3 种访问限定符
C++ 里有public(公有)、protected(保护)、private(私有) 3 种继承方式,同时类的成员也有这 3 种访问限定符,两者组合决定了基类成员在派生类中的访问权限。

(3)基类成员在派生类中的访问变化(必背表)
在这里插入图片描述
1.3 新手必懂的 5 个核心结论

这 5 条结论是理解继承访问规则的关键,记熟了能避开 80% 的基础坑:

1.基类的private成员,无论哪种继承方式,在派生类中都不可见。
✨ 新手注意:“不可见” 不是没继承,而是语法上禁止派生类(类内 + 类外)访问,成员其实还在派生类对象里。
2.**protected限定符是为继承而生的!**如果基类成员不想被类外访问,但想让派生类访问,就定义为protected(比 private 宽松,比 public 严格)。
3.访问权限的简易判断:基类成员在派生类的访问权限 = 最小值 (基类成员的访问限定符,继承方式),权限优先级:public > protected > private。
4.继承方式的默认规则:用class定义类时,默认private 继承;**用struct定义类时,默认public 继承。**✨ 新手建议:显式写出继承方式,别靠默认,代码可读性更高。
5.实际开发中,**只推荐 public 继承!**protected/private 继承的成员只能在派生类内使用,扩展和维护性极差,几乎不用。

2. 基类派生类的 “赋值小规则”—— 对象转换那些事
基类和派生类的对象、指针、引用之间的赋值转换,是笔试高频考点,也是易混点,核心记住 “切片 / 切割” 这个概念,再记 3 条规则就够了。
核心概念:切片 / 切割
派生类对象包含了基类的所有成员 + 自身的专属成员,当派生类对象赋值给基类对象 / 指针 / 引用时,编译器会把派生类中基类那部分成员 “切下来” 赋值过去,这就是切片。

3 条核心赋值规则(理解性记忆)
规则 1:派生类对象 → 基类对象 / 指针 / 引用 ✅(直接赋值,安全)
这是最常用的情况,直接赋值即可,编译器自动完成切片。
例子:

class Person
{
protected:
    string _name;
    string _sex;
    int _age;
};
class Student : public Person
{
public:
    int _No; // 学号
};

void Test()
{
    Student sobj;
    // 子类对象赋值给父类对象/指针/引用,全部可行
    Person pobj = sobj; // 对象赋值
    Person* pp = &sobj; // 指针赋值
    Person& rp = sobj;  // 引用赋值
}

规则 2:基类对象 → 派生类对象 ❌(直接赋值,禁止)
基类对象只有基础成员,没有派生类的专属成员,直接赋值会导致派生类的专属成员无值可赋,编译器直接禁止

sobj = pobj; // 错误!基类对象不能赋值给派生类对象

规则 3:基类指针 / 引用 → 派生类指针 / 引用 ⚠️(强制转换,谨慎使用)
编译器不会自动转换,需要强制类型转换,但只有基类指针 / 引用指向派生类对象时,转换才安全;如果指向基类对象,转换后访问派生类专属成员会越界访问,程序崩溃!

void Test()
{
    Student sobj;
    Person pobj;
    Person* pp;

    // 情况1:基类指针指向派生类对象,强制转换安全
    pp = &sobj;
    Student* ps1 = (Student*)pp;
    ps1->_No = 10; // 正常访问,没问题

    // 情况2:基类指针指向基类对象,强制转换后越界访问!
    pp = &pobj;
    Student* ps2 = (Student*)pp;
    ps2->_No = 10; // 错误!越界访问,程序崩溃
}

✨ 新手拓展:如果基类是多态类型(有虚函数),可以用dynamic_cast进行安全转换,编译器会自动检查类型,后续学多态会详细讲,现在先了解即可。

3. 继承里的 “地盘之争”—— 作用域问题
继承体系中,基类和派生类都有独立的作用域,这是理解 “隐藏(重定义)” 的关键,新手要区分清楚隐藏和重载,别搞混了!
4 条核心规则

  • 基类和派生类是两个独立的作用域,这是隐藏的前提。
  • 子类和父类有同名成员时,子类成员会屏蔽父类对同名成员的直接访问,这种现象叫隐藏(也叫重定义)。
    ✨ 解决方法:在子类中用基类名::基类成员显式访问父类的同名成员。
  • 成员函数的隐藏更 “宽松”:只要函数名相同,就构成隐藏,不管参数列表、返回值是否相同(和重载不同!)。
  • 开发建议:继承体系中,尽量不要定义同名成员,容易混淆,增加调试成本。

例子
例子 1:同名成员变量的隐藏

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

class Person
{
protected:
    string _name = "小李子";
    int _num = 111; // 身份证号(父类的num)
};

class Student : public Person
{
public:
    void Print()
    {
        cout << "姓名:" << _name << endl;
        // 父类num被隐藏,必须用Person::num显式访问
        cout << "身份证号:" << Person::_num << endl;
        // 直接访问的是子类自己的num
        cout << "学号:" << _num << endl;
    }
protected:
    int _num = 999; // 学号(子类的num,和父类同名)
};

void Test()
{
    Student s1;
    s1.Print(); // 输出:小李子 111 999
}

例子 2:同名成员函数的隐藏(区分重载)
重载的前提是同一作用域,而继承中基类和派生类是不同作用域,所以同名函数不是重载,而是隐藏!

#include <iostream>
using namespace std;

class A
{
public:
    void fun()
    {
        cout << "func()" << endl;
    }
};

class B : public A
{
public:
    // 函数名相同,构成隐藏,不管参数是否不同
    void fun(int i)
    {
        A::fun(); // 显式访问父类的fun
        cout << "func(int i)->" << i << endl;
    }
};

void Test()
{
    B b;
    b.fun(10); // 调用子类的fun,输出:func() func(int i)->10
    // b.fun(); // 错误!父类fun被隐藏,直接调用会编译失败
    b.A::fun(); // 正确,显式调用父类fun
}

✨ 新手坑:别以为子类 fun 加了参数就是重载,只要不在同一作用域,永远是隐藏!

4. 派生类的 “六大默认成员函数”—— 编译器帮我们做了啥
C++ 中,类如果不自己写六大默认成员函数,编译器会自动生成,分别是**:构造函数、析构函数、拷贝构造函数、赋值运算符重载、普通对象取地址重载、const 对象取地址重载**(后两个几乎不用自己写,重点看前四个)。

派生类的默认成员函数不是 “凭空生成” 的,而是基于基类的成员函数来初始化 / 清理,核心原则是:先处理基类,再处理派生类(构造);先处理派生类,再处理基类(析构)。

新手必懂的 7 条核心规则
1.派生类的构造函数必须调用基类的构造函数,初始化基类的成员;如果基类没有默认构造函数(无参 / 全缺省),派生类必须在初始化列表中显式调用基类的构造函数。
2.派生类的拷贝构造函数必须调用基类的拷贝构造,完成基类成员的拷贝初始化。
3.派生类的赋值运算符重载(operator=) 必须调用基类的 operator=,完成基类成员的赋值。
4.派生类的析构函数执行完成后,编译器会自动调用基类的析构函数,保证先清理派生类成员,再清理基类成员。
5.派生类对象的初始化顺序:先调用基类构造函数,再调用派生类构造函数。
6.派生类对象的析构顺序:先调用派生类析构函数,再调用基类析构函数(和构造相反)。
7.析构函数的隐藏特殊点:编译器会把所有析构函数名统一处理为destructor(),所以即使子类析构函数名和父类看似不同(都是~类名),也构成隐藏(后续多态会讲如何打破这个隐藏,加 virtual)。

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

// 基类:Person
class Person
{
public:
    // 构造函数
    Person(const char* name = "peter")
        : _name(name)
    {
        cout << "Person()" << endl;
    }

    // 拷贝构造函数
    Person(const Person& p)
        : _name(p._name)
    {
        cout << "Person(const Person& p)" << endl;
    }

    // 赋值运算符重载
    Person& operator=(const Person& p)
    {
        cout << "Person operator=(const Person& p)" << endl;
        if (this != &p)
            _name = p._name;
        return *this;
    }

    // 析构函数
    ~Person()
    {
        cout << "~Person()" << endl;
    }

protected:
    string _name; // 姓名
};

// 派生类:Student
class Student : public Person
{
public:
    // 构造函数:初始化列表显式调用基类构造
    Student(const char* name, int num)
        : Person(name)
        , _num(num)
    {
        cout << "Student()" << endl;
    }

    // 拷贝构造:初始化列表显式调用基类拷贝构造
    Student(const Student& s)
        : Person(s)
        , _num(s._num)
    {
        cout << "Student(const Student& s)" << endl;
    }

    // 赋值运算符重载:显式调用基类的operator=
    Student& operator=(const Student& s)
    {
        cout << "Student& operator=(const Student& s)" << endl;
        if (this != &s)
        {
            Person::operator=(s); // 调用基类的赋值重载
            _num = s._num;        // 赋值自己的成员
        }
        return *this;
    }

    // 析构函数:编译器自动调用基类析构
    ~Student()
    {
        cout << "~Student()" << endl;
    }

protected:
    int _num; // 学号
};

// 测试:看输出顺序,理解构造/析构/拷贝/赋值的过程
void Test()
{
    cout << "---构造s1---" << endl;
    Student s1("jack", 18); // 先Person(),再Student()

    cout << "---拷贝构造s2---" << endl;
    Student s2(s1); // 先Person(const Person& p),再Student(const Student& s)

    cout << "---赋值s1 = s3---" << endl;
    Student s3("rose", 17);
    s1 = s3; // 先Student& operator=,再Person operator=

    cout << "---析构开始---" << endl;
    // 析构顺序:s3→s2→s1,每个对象先~Student(),再~Person()
}

int main()
{
    Test();
    return 0;
}

5. 友元和静态成员的 “继承小脾气”—— 能继承吗?咋用?
继承中,友元关系和静态成员的处理比较特殊,新手容易误以为 “友元能继承”“静态成员每个子类都有一份”,其实都是错的

5.1 继承与友元:友元关系不能继承
核心结论:基类的友元,不能访问派生类的私有 / 保护成员,友元关系是 “一对一” 的,不会随继承传递。
例子:基类 Person 的友元函数 Display,能访问 Person 的成员,但不能直接访问 Student 的_stuNum(除非 Student 也把 Display 声明为友元)。

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

class Student; // 前向声明
class Person
{
public:
    friend void Display(const Person& p, const Student& s);
protected:
    string _name = "peter"; // 姓名
};

class Student : public Person
{
    // 如果不加这行,Display访问_stuNum会报错
    // friend void Display(const Person& p, const Student& s);
protected:
    int _stuNum = 1001; // 学号
};

// 基类友元函数
void Display(const Person& p, const Student& s)
{
    cout << p._name << endl; // 正确,能访问基类保护成员
    // cout << s._stuNum << endl; // 错误!友元不能继承,无法访问子类保护成员
}

int main()
{
    Person p;
    Student s;
    Display(p, s);
    return 0;
}

✨ 注意:如果想让基类友元访问派生类成员,需要在派生类中重新将该友元声明为友元。

5.2 继承与静态成员:静态成员整个继承体系只有一份
核心结论:基类定义的static静态成员,无论派生出多少个子类,整个继承体系中只有一个实例,所有基类和派生类对象共享这个静态成员。
简单来说:静态成员是 “类级别的”,不是 “对象级别的”,继承只是让子类拥有访问权限,不会创建新的静态成员。

#include <iostream>
using namespace std;

class Person
{
public:
    Person() { ++_count; } // 构造一次,计数+1
protected:
    string _name;
public:
    static int _count; // 静态成员:统计人数
};
// 静态成员必须在类外初始化!新手别忘
int Person::_count = 0;

// 子类1:Student
class Student : public Person
{
protected:
    int _stuNum;
};

// 子类2:Graduate(研究生,继承自Student)
class Graduate : public Student
{
protected:
    string _seminarCourse;
};

// 测试:所有子类共享Person的_count
void TestPerson()
{
    Student s1, s2, s3;
    Graduate s4;
    cout << "人数:" << Person::_count << endl; // 输出4,4个对象构造
    cout << "人数:" << Student::_count << endl; // 输出4,子类可直接访问
    cout << "人数:" << Graduate::_count << endl; // 输出4

    Student::_count = 0; // 子类修改,基类也会变
    cout << "人数:" << Person::_count << endl; // 输出0,共享同一份
}

int main()
{
    TestPerson();
    return 0;
}

✨ 坑:静态成员必须在类外初始化,格式是类型 类名::静态成员名 = 初始值,别漏了!

6. 继承里的 “大坑”—— 菱形继承与虚拟继承
菱形继承是 C++ 继承中最复杂的问题,也是笔试高频考点,它是多继承的特殊情况,新手学这部分重点掌握:什么是菱形继承、有什么问题、怎么解决(虚拟继承)、虚拟继承的简单原理。
6.1 先搞懂:单继承 vs 多继承
单继承:一个子类只有一个直接父类,比如Student : public Person,这是最安全的继承方式,推荐使用。
多继承:一个子类有两个及以上直接父类,比如Assistant : public Student, public Teacher,这是菱形继承的根源,实际开发中尽量避免。

6.2 菱形继承:多继承的 “坑中之坑”
(1)什么是菱形继承?
子类的两个直接父类,都继承自同一个基类,形成一个 “菱形” 的继承结构,比如:
Person是基类,Student和Teacher都继承自Person,Assistant(助教)又同时继承自Student和Teacher,结构如下:
在这里插入图片描述

(2)菱形继承的两大致命问题
问题 1:二义性—— 派生类对象访问公共基类的成员时,编译器不知道访问哪个父类的基类成员,直接编译失败。
问题 2:数据冗余—— 派生类对象中,公共基类的成员会存两份(一份来自 Student,一份来自 Teacher),浪费内存。

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

// 公共基类
class Person
{
public:
    string _name = "peter"; // 姓名
};

// 子类1:Student继承Person
class Student : public Person
{
protected:
    int _num; // 学号
};

// 子类2:Teacher继承Person
class Teacher : public Person
{
protected:
    int _id; // 工号
};

// 菱形子类:Assistant继承Student和Teacher
class Assistant : public Student, public Teacher
{
protected:
    string _majorCourse; // 主修课程
};

void Test()
{
    Assistant a;
    // a._name = "tom"; // 错误!二义性,不知道访问Student::_name还是Teacher::_name
    // 解决二义性:显式指定父类
    a.Student::_name = "tom";
    a.Teacher::_name = "jerry";
    // 数据冗余:a中有两份_name,分别是Student和Teacher的
}

6.3 菱形虚拟继承:解决二义性和数据冗余的 “神器”
(1)如何使用虚拟继承?
在公共基类的直接子类(菱形的左右两个子类)继承时,加上virtual关键字,即virtual public 基类名,就能实现虚拟继承,解决菱形继承的两大问题。

修改后的例子(加入 virtual,解决问题):

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

class Person
{
public:
    string _name = "peter";
};

// 加入virtual,虚拟继承Person
class Student : virtual public Person
{
protected:
    int _num;
};

// 加入virtual,虚拟继承Person
class Teacher : virtual public Person
{
protected:
    int _id;
};

class Assistant : public Student, public Teacher
{
protected:
    string _majorCourse;
};

void Test()
{
    Assistant a;
    a._name = "tom"; // 正确!无歧义,只有一份_name
    cout << a._name << endl; // 输出tom
}

✨ 新手注意:virtual 只加在菱形的左右子类上,最底层的子类(Assistant)不用加,加了也没用。

(2)虚拟继承的简单原理(新手浅尝即可,不用深钻底层)
虚拟继承的底层实现比较复杂,新手只需要理解核心逻辑:

虚拟继承会让公共基类的成员在派生类对象中只存一份,并在菱形的左右子类(Student/Teacher)中添加一个虚基表指针,指向一个虚基表;虚基表中存储的是偏移量,通过这个偏移量,子类能找到唯一的公共基类成员,从而解决二义性和数据冗余。

简单来说:虚基表指针就是 “导航仪”,告诉编译器公共基类成员的唯一位置,不用再存两份,也不会找错。
✨ 开发建议:**尽量不要设计多继承,更不要设计菱形继承!**虚拟继承虽然能解决问题,但底层实现复杂,会带来一定的性能开销,实际开发中能避免就避免。

7. 继承的 “灵魂反思”—— 咋用才对?继承 vs 组合
学完继承的所有知识点,新手可能会有一个疑问:既然继承能实现代码复用,那是不是所有场景都用继承?答案是不是!C++ 中还有另一种更推荐的复用方式 ——组合,实际开发中优先使用组合,而非继承。

这部分重点掌握:继承和组合的关系、各自的优缺点、使用场景。

7.1 继承:is-a 关系(是一种)
public 继承的本质是is-a(是一种)关系:每个派生类对象,都是一个基类对象。

// Car是基类,BMW和Benz都是Car的子类,is-a关系
class Car{
protected:
    string _colour = "白色";
    string _num = "陕ABIT00";
};
class BMW : public Car{
public:
    void Drive() {cout << "好开-操控" << endl;}
};
class Benz : public Car{
public:
    void Drive() {cout << "好坐-舒适" << endl;}
};

7.2 组合:has-a 关系(有一个)
组合的本质是has-a(有一个)关系:一个类的对象,包含另一个类的对象。
比如:Car has a Tire(汽车有轮胎),Phone has a Battery(手机有电池),这种 “包含某个部件” 的关系,适合用组合。

// Tire是轮胎类,Car组合Tire,has-a关系
class Tire{
protected:
    string _brand = "Michelin";
    size_t _size = 17;
};
class Car{
protected:
    string _colour = "白色";
    string _num = "陕ABIT00";
    Tire _t; // 组合Tire对象,汽车有轮胎
};

7.3 继承 vs 组合:优缺点对比
在这里插入图片描述
7.4 必懂的使用原则

  • 优先使用组合:组合耦合度低、封装性好、维护性高,是实际开发中更推荐的复用方式。
  • 继承的适用场景:
    类之间是is-a关系时,用继承;
    需要实现多态时,必须用继承(后续学多态会知道,虚函数 + 继承是实现多态的核心)。
  • 折中原则:如果类之间既可以用继承,也可以用组合,优先用组合。

8. 笔试面试高频题 —— 考点速记
继承是 C++ 笔试面试的必考知识点,以下是高频考题,直接背答案即可,覆盖 90% 的考点:

题 1:什么是菱形继承?菱形继承的问题是什么?
答案:菱形继承是多继承的特殊情况,指一个子类的两个直接父类继承自同一个公共基类,形成菱形的继承结构;其核心问题是数据冗余(公共基类成员在派生类中存两份)和二义性(访问公共基类成员时编译器无法确定访问哪个父类的成员)。

题 2:什么是菱形虚拟继承?如何解决数据冗余和二义性的?
答案:在菱形继承的公共基类直接子类上,使用virtual关键字进行的继承就是菱形虚拟继承;虚拟继承让公共基类的成员在派生类对象中只存储一份,同时通过虚基表指针和虚基表(存储偏移量)让子类能唯一找到公共基类成员,从而同时解决数据冗余和二义性问题。

题 3:继承和组合的区别?什么时候用继承?什么时候用组合?
答案:

  • 关系不同:继承是is-a(是一种)关系,组合是has-a(有一个)关系;
  • 复用方式不同:继承是白箱复用(基类细节可见),组合是黑箱复用(被组合类细节隐藏);
  • 耦合度不同:继承耦合度高,组合耦合度低;
  • 封装性不同:继承破坏基类封装,组合封装性好。
    使用场景:
  • 当类之间是is-a关系,或需要实现多态时,用继承;
  • 当类之间是has-a关系,或仅需要代码复用时,优先用组合。

题 4:基类和派生类的对象赋值转换有哪些规则?
答案:
1.派生类对象可以直接赋值给基类对象 / 指针 / 引用(切片,安全);
2.基类对象不能直接赋值给派生类对象(编译器禁止);
3.基类指针 / 引用可以通过强制类型转换赋值给派生类指针 / 引用,但只有基类指针 / 引用指向派生类对象时才安全,否则会越界访问。

题 5:派生类的构造函数和析构函数的执行顺序是什么?
答案:

  • 构造顺序:先调用基类的构造函数,再调用派生类的构造函数;
  • 析构顺序:先调用派生类的析构函数,再调用基类的析构函数(和构造顺序相反),编译器会自动在派生类析构后调用基类析构。

题 6:基类的 private 成员在派生类中能访问吗?protected 成员的作用是什么?
答案:基类的 private 成员在派生类中无论哪种继承方式都不可见,无法访问;protected 成员是为继承而生的,它的作用是:基类的 protected 成员不能被类外访问,但能被派生类访问,兼顾封装性和继承的复用性。

题 7:静态成员在继承体系中的特点是什么?
答案:基类的静态成员在整个继承体系中只有一个实例,所有基类和派生类的对象共享这个静态成员,继承只是让子类拥有对静态成员的访问权限,不会创建新的静态成员。

题 8:友元关系能继承吗?
答案:友元关系不能继承,基类的友元无法访问派生类的私有 / 保护成员,如果需要访问,必须在派生类中重新将该友元声明为友元。

uniapp - 解决App端报错reportJSException >>>> exception function:createInstanceContext, exception:white sc uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果安卓app,uniApp报错,reportJSException>>>>exceptionfunction:createInstanceContext,exception:whitescreencausecreateinstanceContextfailed,运行自定义基座时白屏,uniapp项目运行白屏reportJSException,检查没问题依旧报错,第三方库插件,组件,uniapp打包调试 阅读详情

相关推荐

STM32中RS485方向控制引脚应用详解

深入解析STM32如何通过GPIO控制RS485通讯的方向引脚,实现半双工通信的精准切换。重点讲解硬件连接与软件时序配合,确保rs485通讯稳定可靠,适用于工业控制等实际场景。

weixin_42451850的博客 400

C++进阶-继承1

本文介绍了C++中面向对象编程的重要概念——继承。主要内容包括:1.继承的基本概念,通过Person、Student和Teacher类示例说明如何复用公共代码;2.继承的三种方式(public、protected、private)及其对基类成员访问权限的影响;3.基类与派生类间的转换规则(切片/切割);4.继承中的作用域和隐藏规则;5.继承与友元、静态成员的关系。文章强调public继承是最常用的方式,并指出继承是类设计层次的复用机制,能有效减少代码冗余。最后预告下一讲将深入探讨继承的更多特性。

博客是在C++/Java/Liunx/算法的学习阶段所写的博客,内容可能不是很全面 794

安卓7.0+抓包难题:雷电模拟器9.0+Charles系统证书安装全攻略

HTTPS协议通过SSL/TLS加密保障网络通信安全,其核心机制依赖于证书信任链。在Android系统中,自7.0版本起,谷歌收紧了证书信任策略,默认仅信任系统预置的CA证书,这直接导致了传统抓包方法失效。理解这一原理对于移动开发、测试及安全研究至关重要,它揭示了应用层安全策略与系统底层机制的关联。通过将用户证书安装至系统信任区,可以突破此限制,实现HTTPS流量的解密与分析。这一技术在App调试、接口测试、安全审计等场景中具有广泛的应用价值。本文以雷电模拟器9.0和Charles抓包工具为例,详细演示了如

weixin_42521843的博客 280

C++进阶(1)——继承

本文系统介绍了C++中的继承机制,主要内容包括: 继承的基本概念和语法,通过学生/教师示例展示派生类继承基类成员的过程; 继承方式对访问权限的影响,详细说明public/protected/private继承的差异; 继承中的特殊处理:默认成员函数、作用域隐藏规则、友元关系、静态成员特性; 多继承与菱形继承问题,重点讲解虚拟继承解决二义性和数据冗余的原理; 继承(is-a)与组合(has-a)的对比分析,指出组合在代码维护性和耦合度上的优势。文章通过大量代码示例和内存布局分析,全面阐述了继承机制的实现原理和

2301_80065652的博客 8344

vue3接入大华摄像头

┃ ┃ ┣ 📜PlaybackModal.vue 回放列表模态框。┃ ┃ ┗ 📜VideoGrid.vue 视频播放区域。┃ ┃ ┣ 📜ControlPanel.vue 控制面板。┃ ┃ ┣ 📜DeviceList.vue 设备列表。┃ ┣ 📂module //大华摄像头文件。

💻 专注 Vue 前端与 Java 后端技术 🌱 目前正在深入 Spring Boot、微服务与性能优化 📝 定期分享实战踩坑经验与学习笔记 🤝 欢迎交流,共同进步 914

C#客户端对接工厂MES的方法

本文介绍了使用C#实现WebApi客户端与工厂MES系统交互的方法。主要包括四个步骤:1)配置工控机IP地址;2)获取服务器URL;3)创建HttpHelper帮助类实现单例模式HttpClient,提供异步POST请求方法;4)通过实例化帮助类实现设备状态数据的JSON格式发送与接收。该方案采用异步通信方式,支持超时处理,能够满足大多数MES系统交互需求,帮助工程师快速完成设备与MES系统的数据对接。文中给出了核心代码片段和完整的数据交互流程示例。

weixin_39832501的博客 265

【C++进阶】第1课—继承

简单来说,继承就是面对对象中复用类的一种手段,它使得两个类之间可以产生关联,一个类可以在另一个类的基础上进行扩展,这两个类也被称为基类(父类)和派生类(子类)之前我们学过函数之间的复用,继承就是类之间进行复用,因此继承的核心也就是复用类成员/继承方式public继承protected继承private继承基类的public成员是派生类的public成员派生类的protected成员派生类的private成员基类的protected成员是派生类的protected成员。

weixin_70620792的博客 947

基于YOLO系列的安全帽检测系统:从理论到实现的完整指南

安全帽检测作为计算机视觉在工业安全领域的重要应用,近年来得到了广泛关注。本文详细介绍了基于YOLOv5、YOLOv6、YOLOv7和YOLOv8的安全帽检测系统的完整实现方案,包括算法原理、数据集构建、模型训练、性能优化以及完整的UI界面设计。通过对比分析不同YOLO版本的性能差异,本文为工业安全检测系统的开发提供了全面的技术参考和实践指导。

YOLO 364

C++进阶 | [1] 继承

摘要:继承的概念,赋值兼容规则,继承中的作用域,派生类的默认成员函数,继承和友元,静态成员的继承,菱形继承和菱形虚拟继承

fantastic_13_7的博客 653

IPCP(IP Control Protocol,IP控制协议)

IPCP(IP Control Protocol,IP控制协议)

天赐好车的博客 756

6、云计算中的多核技术:架构、并行性与局限性

本博文深入探讨了云计算中多核技术的架构、并行性及其局限性。文章详细介绍了多核处理器的基础概念、并行硬件和软件的设计原理,并对硬件和软件并行性进行了分类和分析。同时,文章讨论了多核架构在实际应用中面临的挑战,如功率墙、内存墙和ILP墙等问题,并提出了应对策略。此外,还总结了多核技术在高性能计算、实时处理和云计算等领域的应用机遇。文章旨在帮助读者更好地理解多核技术的关键问题,并为未来的技术探索提供方向。

java5的博客 122

C++进阶知识1继承

1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承基类成员访问⽅式的变化 1.3 继承类模板 2. 基类和派⽣类间的转换 3. 继承中的作⽤域 3.1 隐藏规则: 4. 派⽣类的默认成员函数 4.1 4个常⻅默认成员函数 4.2 实现⼀个不能被继承的类 5. 继承与友元 6. 继承与静态成员 7. 多继承及其菱形继承问题 7.1 继承模型 7.2 虚继承 8. 继承和组合

Yusei_0523的博客 998

滑模观测器与锁相环结合应用:让电机“无感”也能精准旋转的奥秘

本文介绍了永磁同步电机无传感器控制中的滑模观测器(SMO)结合锁相环(PLL)技术。SMO通过创建虚拟电机模型,利用电流误差产生控制信号来估计反电动势;PLL则从反电动势中解码转子位置和速度信息。该组合方案兼具SMO的鲁棒性和PLL的高精度,计算量小且硬件要求低。文章详细阐述了原理、数学模型、参数整定方法及实际实现技巧,包括离散化处理、符号函数替代等优化手段,并分析了低速性能限制、抖振问题等常见挑战及解决方案。最后指出该技术未来将与人工智能、多观测器融合等方向结合发展。

汽车软件开发 195

C++进阶-1-单继承、多继承、虚继承

C++中的继承是一种重要的面向对象编程特性,使得代码的组织和结构变得更加清晰。在设计类结构时,应根据项目需求和复杂性,合理选择单继承或多重继承等。

小王爱吃月亮糖的博客 1897

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C++进阶——继承 (1)

本文介绍了C++继承机制的核心概念与应用。主要内容包括:1. 继承的基本概念与定义方式,通过Person/Student/Teacher类示例说明代码复用优势;2. 继承中的访问控制规则,分析不同继承方式对成员可见性的影响;3. 基类与派生类的转换规则,重点讲解"切片"特性;4. 继承体系中的作用域问题,特别是同名成员的隐藏规则;5. 派生类默认成员函数的实现要点,包括构造/拷贝/赋值/析构函数的调用顺序;6. 实现不可继承类的两种方法(私有构造/final关键字)。

Linux、C++、图形软件开发等。不一定每次都能写出完美的代码,但会认真搞懂每一个问题。 2056

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【C++进阶】1. 继承

该篇博客包含对继承的学习,包括继承的概念,基类和派生类对象的赋值转换,继承的作用域,派生类的默认成员函数,继承和友元关系,继承与静态成员,多继承,菱形继承和解决菱形继承问题的虚拟继承 .....

哈茶的博客 331

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C++进阶:1_C++中的继承

下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。继承和组合(组合和继承都是一种复用)这里讨论共有继承public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。

Open__Ai的博客 924

C++进阶1:继承深度解析

如果你写过重复的类代码(比如 “学生” 和 “教师” 都需要 “姓名、年龄” 属性),一定懂这种 “复制粘贴” 的痛苦。而 C++ 的继承正是解决这个问题的核心:它让子类(派生类)能 “继承” 父类(基类)的属性和方法,同时扩展自己的功能,是面向对象三大特性(封装、继承、多态)的核心之一。这篇博客会沿着 “基础概念→语法细节→进阶问题” 的脉络,把继承的核心知识点拆成 “概念 + 代码示例 + 实战场景”,从 “单继承” 到 “菱形继承的坑”,帮你彻底搞懂 C++ 继承的逻辑。

chen060603的博客 604

C++_进阶_1_继承

C++_进阶—1_继承 文章目录C++_进阶—1_继承面向对象的三大特性: 面向对象的三大特性: 封装:封装本质是一种更好的管理 相对C语言面向过程,把数据和方法都放在类中进行管理,再通过访问限定符进行限制。 继承:从类设计角度讲, 在设计如下类的时候: 由于Teacher,Student有很多相似的属性 多态 ...

成功的方式只有一个,按自己的方式,度过人生。欢迎共赴知识与乐趣的探索之旅! 459

C++进阶(1)C++中的继承

C++中的继承

2301_79907403的博客 556

C++进阶——继承(1)(用法)

详细讲述继承的概念,用法,内涵,希望大家能够理解,不断提升自己的能力。

2301_80681378的博客 678

C/C++ 进阶(1)继承

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。对于不同的类,可能会有相同的属性,如果在每一个类中都存一份相同的属性,可能会属性冗余。这样我们就可以把相同的属性拿出来,单独设置成一个类,然后成为父类(基类)这个表格挺重要的!!!

敲代码嘞~的博客 868

【C++进阶】:(1)继承机制详解

为什么需要继承↓基类和派生类↓继承权限↓派生类向基类转换↓同名成员隐藏↓构造、拷贝、赋值、析构↓多继承和菱形继承↓虚继承↓继承与组合基类部分派生类自己的部分理解这一点之后,很多知识都会顺下来。可以转换;为什么派生类构造之前要先构造基类;为什么析构时又要反过来;为什么多继承时不同基类指针可能存在地址偏移;这些问题其实都和对象内部的组成结构有关。is-a -> 继承has-a -> 组合继承并不只是为了少写几行代码,更重要的是表达不同类之间真正存在的逻辑关系。

2501_90703620的博客 278

C++进阶必备:继承与多态的通关秘籍(1):继承详解!!

本文详细讲解了继承与多态的核心概念和使用方法。首先介绍了继承的基本概念、三种继承方式及其访问限定符的变化规则,重点阐述了基类与派生类之间的转换赋值规则。然后深入剖析了派生类默认成员函数的实现机制,特别是构造函数和析构函数的调用顺序问题。接着讨论了继承中的特殊场景,包括友元关系、静态成员和多继承问题。最后指出了菱形继承的潜在风险,建议谨慎使用多继承。文章通过大量代码示例帮助读者理解继承机制中的常见的坑,为后续学习多态打下基础。

liriying的博客 957

C++进阶篇1---继承

C++进阶篇1----继承

V_zjs的博客 451

【C++进阶1--继承】面向对象三大特性之一(附菱形继承讲解

C++的继承,懂的都懂~菱形继承看这里

BaconZzz的博客 869
上一篇: C++12(模板进阶)
下一篇: C++进阶2(多态)
code_whiter
博客等级 码龄2年 289粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值