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日

相关文章

  • C语言实现高精度加减法

    C语言实现高精度加减法 简介 高精度计算是指多位数的加、减、乘、除等算法。在计算机程序设计中,常常需要进行高精度计算。C语言是一种强大的编程语言,可以通过C语言实现高精度的加、减法运算。 实现思路 1. 字符串存储 高精度计算需要用到大量的数字,超过了C语言中能够表示的整型、浮点型数据类型范围,因此可以采用字符串存储数字。 2. 进位处理 在高精度计算中,进…

    C 2023年5月23日
    00
  • C++11实现简易定时器的示例代码

    下面是关于“C++11实现简易定时器的示例代码”的完整攻略。 标题 C++11实现简易定时器的示例代码 简介 在开发事件驱动或多线程程序时,经常需要一种定时器来控制任务的执行时间。本篇攻略将介绍如何使用C++11编写一个简易的定时器,以此来满足我们在各种场景中的需求。 本攻略将包含两个实例展示如何使用简易定时器,读者可以通过这两个实例学习如何将其应用于自己的…

    C 2023年5月22日
    00
  • JS循环遍历JSON数据的方法

    以下是详细的讲解”JS循环遍历JSON数据的方法”的完整攻略: 1. 解析JSON数据 在JS中,可以通过JSON.parse将字符串转换为JSON对象,也可以直接将JSON数据引入JS文件中,得到一个JSON对象。解析成功后,我们即可对JSON数据进行操作。 1.1 解析字符串为JSON对象 const jsonData = ‘{"name&qu…

    C 2023年5月23日
    00
  • C语言实现的学生选课系统代码分享

    C语言实现的学生选课系统代码分享 简介 本文将分享一份用C语言实现的学生选课系统代码,该系统实现了学生的选课、退课、成绩查看等功能。通过学习本系统的代码,可以加深对C语法及数据结构的理解。 功能模块 学生选课系统包含了以下几个功能模块: 学生信息管理 课程信息管理 学生选课 学生退课 成绩查询 数据结构 该系统使用了以下数据结构: 结构体:用于存储学生信息、…

    C 2023年5月23日
    00
  • 毕业答辩的ppt怎么写? 毕业答辩的ppt的制作技巧

    下面是毕业答辩PPT的制作攻略,分为以下几个步骤: 1.明确PPT的目的和主题 在制作PPT之前,我们需要先想清楚PPT的主题和目的,展示内容和要讲解的重点,对于毕业答辩PPT来说,最好能够简洁明了地介绍自己的研究方向、主要研究内容和研究成果。 2.制作PPT的结构 PPT的结构要清晰且合理,通过分章节、剖析问题、展示数据等多种方式为听众呈现自己的研究成果。…

    C 2023年5月22日
    00
  • 详解C++17中nodiscard标记符的使用

    下面是详解C++17中nodiscard标记符的使用的完整攻略。 什么是nodiscard标记符? nodiscard是C++17标准引入的一个标记符,在函数声明或定义中加入它可以告诉编译器该函数的返回值不能被忽略。在使用nodiscard标记符的情况下,如果函数返回值被忽略,编译器将给出警告。 when和where to use nodiscard标记符?…

    C 2023年5月23日
    00
  • 如何在TC2.0中调用汇编程序

    当我们需要使用汇编语言实现某些特定的功能,或者需要使用一些特殊的指令时,可以考虑在TC2.0中调用汇编程序。下面是在TC2.0中调用汇编程序的详细攻略: 1. 创建汇编源文件 首先,需要创建一个汇编文件,以实现所需的功能。在Windows环境中,可以使用文本编辑器或者IDE,比如Notepad++,来创建汇编文件。以MASM语法为例,文件的扩展名应为.asm…

    C 2023年5月23日
    00
  • C语言实现简易通讯录完整流程

    C语言实现简易通讯录完整流程 1. 需求分析 在编写“C语言实现简易通讯录”的过程中,我们需要实现以下功能:1. 添加联系人2. 删除联系人3. 修改联系人4. 查找联系人5. 显示联系人 2. 思路设计 2.1 数据结构设计 为了实现通讯录功能,我们可以定义如下结构体存储联系人信息: #define NAME_MAX_LENGTH 20 #define P…

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