C++深入探究类与对象之友元与运算符重载

C++深入探究类与对象之友元与运算符重载

友元(friend)是 C++ 中比较特殊的概念,它可以使一个类中的非成员函数访问类的私有成员,非常适合于一些特殊的应用场景。本文将深入讲解 C++ 中友元的使用方法并结合示例进行说明。

友元的概念

在 C++ 中,我们可以使用关键字 friend 定义友元,其作用是允许其他类或者函数访问该类的私有成员。简而言之,友元关系特指的是在某类内部所定义的非成员函数以及其他类,与该类对象有特殊的访问权限。

友元的使用方法

我们可以将友元函数作为该类的友元,也可以将其他类作为该类的友元。为了使用友元,需要遵守以下两点:

  1. 友元函数的声明必须放在目标类(被授权)的定义内部。
  2. 友元类的声明必须放在目标类(被授权)的定义内部,而其定义可以在任意位置。

具体使用方法如下:

  1. 友元函数的使用方法
class A {
    friend void B(A&);  // 在类内声明B为友元函数
    ...
};
void B(A &a){ ... }    // 友元函数B的定义
  1. 友元类的使用方法
class A {
    friend class B;  // 在类内声明B为友元类
    ...
};
class B {
    ...
};    // 注意:B类的定义可以在定义A类之后

运算符重载

运算符重载是 C++ 独有的一种特性,它允许我们对 C++ 已经定义好的运算符进行重新定义。我们可以为任意数据类型定义自己的运算符行为,使其支持加减乘除等各种运算。

为了实现这个特性,我们需要为自定义类型定义运算符重载函数,将要重载的运算符作为函数名,同时使用 operator 作为前缀,示例如下:

class Vector {
public:
    ...
    Vector operator + (const Vector &rhs) const;  // 定义加法运算符
    ...
};

以上定义重载了 + 运算符,使得 Vector 类型支持加法运算。运算符重载函数可以被设计为类的成员函数,也可以是非成员函数,其中成员函数一般用于比较两个类的对象,非成员函数一般用于实现新的类型或实现更高效的算法。具体示例如下:

class MyInt {
public:
    ...
    MyInt operator + (const MyInt &rhs) const;  // 作为类成员函数
};
MyInt operator + (const MyInt& lhs, const MyInt& rhs) {  // 作为非成员函数
    return MyInt(lhs.m_value + rhs.m_value);
}

示例说明

友元示例

以下示例定义了一个 Point 类,其中包含 x 和 y 坐标,同时包含了一个私有的构造函数 Point(int, int) 和一个友元函数 distance(const Point&, const Point&)

class Point {
public:
    Point(int x = 0, int y = 0) : m_x(x), m_y(y) {}
    friend double distance(const Point& p1, const Point& p2);
private:
    int m_x, m_y;
};
double distance(const Point& p1, const Point& p2) {
    int dx = p1.m_x - p2.m_x;
    int dy = p1.m_y - p2.m_y;
    return sqrt(dx * dx + dy * dy);
}

int main() {
    Point p1(1, 2);
    Point p2(3, 4);
    cout << distance(p1, p2) << endl;  // 输出距离为2.82843
    return 0;
}

本示例中,我们定义了一个 distance 函数,该函数通过使用友元关系,实现了访问 Point 类的私有成员。在主函数中,我们通过调用该函数计算了两个 Point 对象之间的距离并输出。

运算符重载示例

以下示例定义了一个 MyString 类,并对加法运算符进行了重载。

class MyString {
public:
    MyString(const char* str) {
        m_data = new char[strlen(str) + 1];
        strcpy(m_data, str);
    }
    MyString operator + (const MyString &rhs) const {
        char* new_data = new char[strlen(m_data) + strlen(rhs.m_data) + 1];
        strcpy(new_data, m_data);
        strcat(new_data, rhs.m_data);
        return MyString(new_data);
    }
    char* get_data() const { return m_data; }
private:
    char* m_data;
};

int main() {
    MyString s1("Hello ");
    MyString s2("world!");
    MyString s3 = s1 + s2;
    cout << s3.get_data() << endl;  // 输出结果为"Hello world!"
    return 0;
}

以上示例中,我们定义了一个 MyString 类,它包含一个 char* 类型的指针用来保存字符串数据。我们在该类中定义了加法运算符 + 的重载函数,实现了两个 MyString 对象的字符串相加。在主函数中,我们实例化了两个 MyString 对象,并通过重载的加法运算符把它们相加,最终输出结果为 "Hello world!",验证了重载函数的正确性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++深入探究类与对象之友元与运算符重载 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 尼尔机械纪元赌徒斗兽场关卡怎么过 赌徒斗兽场全关卡打法攻略

    尼尔机械纪元赌徒斗兽场关卡怎么过? 简介 赌徒斗兽场是尼尔机械纪元(Nier: Automata)游戏中一个非常经典的关卡。该关卡要求玩家在斗兽场中打败各种强大的机器生物,挑战难度非常高。 过程 关卡1 第一关卡的挑战难度相对较低,只需要打败一只级别为2的机器人即可。示例: 战斗开始后,尽可能回避机器人的攻击,不断躲避并进行反击。当机器人血量降至微弱时,利用…

    C 2023年5月22日
    00
  • C++常量详解二(常量形参,常量返回值,常量成员函数)

    C++常量详解二(常量形参、常量返回值、常量成员函数) 常量形参 在 C++ 中,函数参数也可以定义为常量。这意味着该参数的值不能被修改。我们可以使用 const 关键字在函数参数中声明它为常量。 void func(const int num) { // 禁止修改 num 的值 } 常量返回值 在 C++ 中,有时我们需要返回一个常量值。这可以通过在函数声…

    C 2023年5月22日
    00
  • C语言实现宿舍管理系统设计

    C语言实现宿舍管理系统设计 1. 项目简介 本项目是一个基于C语言的宿舍管理系统,具有学生管理、宿舍管理、归寝管理、公告管理等多个功能。系统通过命令行界面进行操作,主要针对大学的学生宿舍进行管理。宿舍管理员可以通过此系统方便地对宿舍进行管理,包括学生信息的添加、删除、修改,宿舍信息的查询、修改等。 2. 实现思路 本项目的实现主要包括以下几个部分: 2.1 …

    C 2023年5月23日
    00
  • php7 错误处理机制修改实例分析

    PHP7 错误处理机制修改实例分析 一、背景 在PHP7中,错误处理机制发生了一些变化。具体来说,PHP7增加了Throwable接口和Error类,用于代替旧版的Exception类。此外,PHP7还引入了一种新的错误处理器:Throwable处理器。Throwable处理器是一种标准的PHP异常处理方式,可以通过使用try-catch语句来捕获和处理所有…

    C 2023年5月22日
    00
  • iOS之异常与信号使用场景分析

    iOS之异常与信号使用场景分析 异常 什么是异常 异常是指运行期间发生错误,导致应用程序不能正常执行的事件,例如:数组越界访问、空指针引用等。在OC中,异常时指通过在方法内部 raise 一个异常对象实例来表示异常事件的。 异常处理 在OC中,我们可以通过以下两个关键字来处理异常: @try: 被检测的代码中可能发生异常的部分需要放在这个语句块里; @cat…

    C 2023年5月23日
    00
  • C/C++高精度(加减乘除)算法的实现

    C/C++高精度算法实现方法 背景 C/C++内置的整型数据类型(int、long等)的取值范围都有限制,例如int类型的取值范围为-2147483648~2147483647,这个取值范围对于绝大部分的算法应用是足够的。但是有时候我们需要进行很大数的计算,此时常规的整型数据类型就无能为力了。这时我们需要实现高精度算法来解决这个问题。 实现 高精度算法的实现…

    C 2023年5月23日
    00
  • 使用C语言编写基于TCP协议的Socket通讯程序实例分享

    本篇文章的主要目标是向大家分享如何使用C语言编写基于TCP协议的Socket通讯程序。这个过程分为以下几个步骤: 步骤一:创建Socket 首先,我们需要创建一个Socket。Socket是一个用于数据传输的端点,可以理解为建立数据传输通道的道具。在C语言中,我们可以使用socket()函数创建Socket。具体代码如下: int sockfd = sock…

    C 2023年5月24日
    00
  • win10系统出现0x000000c5蓝屏的修复方法

    Win10系统出现0x000000c5蓝屏的修复方法 前言 在Windows10系统运行过程中,可能会碰到各种各样的蓝屏错误。其中,0x000000c5蓝屏错误是较为常见的一种,表示驱动程序试图访问非法内存地址。这可能是因为驱动程序不能正确处理该内存地址,或者因为某些未知原因导致内存地址错误。本文将详细介绍修复0x000000c5蓝屏错误的步骤。 步骤 步骤…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部