1.继承与友元

 核心结论:友元关系不能被继承!

1.什么是友元

友元是一种授权机制:
允许外部函数 / 外部类,访问一个类的 private/protected 成员。
友元关系是单向、不可传递、不可继承的。

2.友元关系不继承


基类的友元 ≠ 派生类的友元
友元只能访问当前声明它的类的成员,无法自动访问子类成员

继承不会传递友元权限

3.友元函数 + 继承
#include <iostream>
using namespace std;

// 基类
class Person {
private:
    string name = "张三";
    // 声明友元函数
    friend void show(Person& p);
};

// 基类的友元函数
void show(Person& p) {
    cout << "访问基类私有成员:" << p.name << endl; // ✅ 合法
}

// 派生类
class Student : public Person {
private:
    // 派生类独有私有成员
    int id = 1001;
};

int main() {
    Student s;
    show(s); // ✅ 可以调用(向上转型),但只能访问基类成员
    
    // show函数 无法访问 s.id ❌ 因为友元没有被继承!
    return 0;
}

友元函数 show 只能访问基类 Person 的成员,
不能访问派生类 Student 的私有成员 id。

4.友元类 + 继承
#include <iostream>
using namespace std;

class Student; // 提前声明

// 基类
class Person {
private:
    string name = "李四";
    // 声明 Teacher 为友元类
    friend class Teacher;
};

// 派生类
class Student : public Person {
private:
    int id = 1002; // 子类私有成员
};

// 基类的友元类
class Teacher {
public:
    void visit(Person& p, Student& s) {
        cout << "访问基类:" << p.name << endl; // ✅ 合法
        
        // 访问派生类私有成员 id ❌ 报错!友元不继承
        // cout << "访问子类:" << s.id << endl;
    }
};

友元类 Teacher 可以访问基类 Person,
无权访问派生类 Student 的独有成员。

2.复杂的菱形继承及菱形虚拟继承

1.什么是菱形继承

四个类形成菱形的继承关系(多继承的特殊情况):
1.一个顶级基类(公共父类)
2.两个中间派生类,同时继承这个顶级基类
3.一个最终派生类,同时继承这两个中间类

2. 经典菱形结构图示

3.普通菱形继承的致命问题
#include <iostream>
using namespace std;

// 顶级基类
class Person {
public:
    int m_age; // 年龄
};

// 中间类1:老师
class Teacher : public Person {
public:
    int m_teach_id;
};

// 中间类2:学生
class Student : public Person {
public:
    int m_stu_id;
};

// 最终类:助教(多继承)
class Assistant : public Teacher, public Student {};
int main() {
    Assistant ass;
    // 1. 赋值报错:二义性!编译器不知道用哪个Person的m_age
    // ass.m_age = 18; 
    
    // 2. 数据冗余!Assistant对象里有**两份** m_age
    ass.Teacher::m_age = 18;
    ass.Student::m_age = 20; 
    
    return 0;
}

二义性:访问顶级基类成员时,编译器分不清是哪个父类的成员
数据冗余:最终对象会存储多份顶级基类的成员,浪费内存

4.解决方案:菱形虚拟继承

核心作用:让最终派生类只保留一份顶级基类的成员,彻底解决二义性 + 数据冗余。
语法:在中间派生类继承时,加上关键字 virtual

class 中间类 : virtual public 顶级基类 {};

菱形虚拟继承代码(正确版):

#include <iostream>
using namespace std;

// 顶级基类
class Person {
public:
    int m_age;
};

// 虚拟继承!中间类加 virtual
class Teacher : virtual public Person {
public:
    int m_teach_id;
};

// 虚拟继承!中间类加 virtual
class Student : virtual public Person {
public:
    int m_stu_id;
};

// 最终类:多继承
class Assistant : public Teacher, public Student {};

int main() {
    Assistant ass;
    ass.m_age = 18; // ✅ 正常!只有一份m_age,无歧义
    cout << ass.m_age << endl; // 输出 18
    return 0;
}

无二义性:直接访问 m_age 不报错
无数据冗余:Assistant 只存一份 Person 成员

谢谢

更多推荐