21.继承中的友元和运算符重载

21.面向对象-继承-继承中的友元和运算符重载


21.1 知识点

知识回顾 友元和运算符重载

  • 友元:

    • 友元是 C++ 中的一个关键字:friend(朋友)
    • 使用友元机制允许我们在外部访问某个类的私有(private)或保护(protected)的成员
    • 我们之前学习的友元函数和友元类,都是基于友元的这一机制的
  • 运算符重载:

    • 概念:让自定义类和结构体能够使用运算符

继承中的友元

  • 友元关系不会被继承,父类和子类中的友元关系彼此独立
#pragma once
class Father
{
    friend void Test();
private:
    int i = 10;
};
#pragma once
#include "Father.h"
class Son : public Father
{
private:
    int j = 20;
};
#include "Father.h"
#include "Son.h"
#include <iostream>
using namespace std;

void Test()
{
    Father f;
    cout << f.i << endl;

    //友元关系 是不会被继承的 
    //因此 父类中的友元方法 是无法去访问子类中的 私有或保护内容的
    Son s;
    //cout << s.j << endl;
}

继承中的运算符重载

  • 运算符重载可以被继承
#pragma once
class Father
{
    friend void Test();
private:
    int i = 10;
public:
    int operator+(const int& i) const;
};
#include "Father.h"
#include "Son.h"
#include <iostream>
using namespace std;

int Father::operator+(const int& i) const
{
    return this->i + i;
}
Son s;
int i = s + 10;
cout << i << endl; //20

21.2 知识点代码

Father.h

#pragma once
class Father
{
    friend void Test();
private:
    int i = 10;
public:
    int operator+(const int& i) const;
};

Father.cpp

#include "Father.h"
#include "Son.h"
#include <iostream>
using namespace std;

int Father::operator+(const int& i) const
{
    return this->i + i;
}

void Test()
{
    Father f;
    cout << f.i << endl;

    //友元关系 是不会被继承的 
    //因此 父类中的友元方法 是无法去访问子类中的 私有或保护内容的
    Son s;
    //cout << s.j << endl;//报错
}

Son.cpp

#pragma once
#include "Father.h"
class Son : public Father
{
private:
    int j = 20;
};

Lesson21_面向对象_继承_继承中的友元和运算符重载.cpp

#include <iostream>
#include "Son.h"
using namespace std;
int main()
{
    #pragma region 知识回顾
    //友元:
    //友元是C++中的一个关键字:friend(朋友)
    //使用友元机制允许 
    //我们在外部访问某个类的
    //私有(private)或保护(protected)的成员
    //我们之前学习的友元函数和友元类,都是基于友元的这一机制的

    //运算符重载:
    //概念
    //让自定义类和结构体
    //能够使用运算符
    #pragma endregion

    #pragma region 知识点一 继承中的友元
    //友元关系不会被继承
    //父类和子类中的友元关系彼此独立
    #pragma endregion

    #pragma region 知识点二 继承中的运算符重载
    //运算符重载可以被继承
    Son s;
    int i = s + 10;
    cout << i << endl;//20
    #pragma endregion

}

21.3 练习题

关于 C++ 中 friend 的继承行为,以下说法正确的是?

A. 父类的 friend 函数在子类中自动也具有 friend 权限
B. friend 函数可以访问类的 private 成员,但不能访问 protected 成员
C. 子类若希望某函数成为友元,必须再次声明为 friend
D. friend 函数是类的成员函数,可以被继承

正确答案:C

解析:

  • A 错误:父类声明的 friend 函数只是对父类有效,并不会自动对所有子类生效。
  • B 错误friend 函数拥有对类所有私有和保护成员的访问权限,不存在只能访问 private 而不能访问 protected 的情况。
  • C 正确:如果想让某个函数在子类中也具有友元权限,必须在子类内部再次使用 friend 声明。
  • D 错误friend 函数并不是类的成员函数,而是一个独立的非成员函数(或另一个类的成员函数),不会被继承。

下列关于运算符重载在继承中的说法,哪个是正确的?

A. 所有重载的运算符都可以自动继承到子类
B. 成员函数形式的运算符重载可以被继承,非成员函数形式的不能
C. 运算符重载必须是虚函数,才能在子类中重写
D. 运算符重载在派生类中不会受到名称隐藏影响

正确答案:B

解析:

  • A 错误:非成员函数形式的运算符重载(如全局重载)不会因为继承而自动对派生类生效。
  • B 正确:以成员函数形式定义的运算符重载会随类的继承关系被继承到子类;非成员(全局)形式的并不会。
  • C 错误:运算符重载并不需要声明为虚函数才能在子类中重新定义;虚函数只影响多态机制,与运算符重载继承无直接关系。
  • D 错误:派生类如果定义了同名运算符重载,会发生名称隐藏,需要使用 using 声明或全名调用才能访问基类版本。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏