友元

本文展示了一个简单的C++程序,该程序通过自定义的Time和Date类来模拟时间的递增及显示。Time类负责处理秒数的增加,并考虑进日期的变化;Date类则跟踪日期变化。程序演示了如何在每增加一秒后更新时间和日期,并输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*   
02.* 程序的版权和版本声明部分   
03.* Copyright (c)2012, 烟台大学计算机学院学生   
04.* All rightsreserved.   
05.* 文件名称: object.cpp   
06.* 作者:刘明亮   
07.* 完成日期: 2013年 4 月16日   
08.* 版本号: v1.0   
09.* 输入描述:   
10.* 问题描述:   
11.* 程序输出:   
*/      

#include<iostream>
using namespace std;
class Date; //对Date类的提前引用声明
class Time
{
public:
    Time(int,int,int);
    void add_a_second(Date &);  //增加1秒,1秒后可能会到了下一天,乃到下一月、下一年
    void display(Date &);  //显示时间,格式:月/日/年 时:分:秒
private:
    int hour;
    int minute;
    int sec;
};

class Date
{
public:
    Date(int,int,int);
    friend class Time; //Time为Date的友元类
private:
    int month;
    int day;
    int year;
};
int main( )
{
    Time t1(23,59,32);
    Date d1(12,25,2012);
    for(int i=0; i<=80; i++)
    {
        t1.add_a_second(d1);
        t1.display(d1);
    }
    return 0;
}

//下面定义两个类中的成员函数,要求不得再增加成员函数
//注意体会在Time的成员函数中可以调用Date类的私有数据成员
Time::Time(int h,int m,int s)
{
    hour=h;
    minute=m;
    sec=s;
}

Date::Date(int m,int d,int y)
{
    year=y;
    month=m;
    day=d;
}

void Time::add_a_second(Date &d)
{
    if(++sec>=60){
        minute+=(sec/60);
        sec%=60;

    }
    if(minute>=60){
        hour+=(minute/60);
        minute%=60;

    }
    if(hour>=24){
        d.day+=(hour/24);
        hour%=24;

    }
    if(d.day>30){
        d.month+=(d.day/30);
        d.day%=30;

    }
    if(d.month>12){
        d.year+=(d.month/12);
        d.month%=12;

    }
}

void Time::display(Date &d)
{
    cout<<d.year<<"/"<<d.month<<"/"<<d.day<<"  "<<hour<<":"<<minute<<":"<<sec<<endl;
}

<think>我们正在讨论C++中的友元函数和友元类概念。根据用户的问题,需要解释这两个概念。 引用中并没有直接关于友元的内容,但我们可以根据C++知识进行解释。 注意:用户要求使用中文回答,并且按照系统级指令格式化数学表达式(如果有的话,但本题可能没有数学表达式,所以主要关注代码格式)。 另外,需要生成相关问题。 步骤: 1. 解释友元函数:友元函数是一个非成员函数,但它可以访问类的私有(private)和保护(protected)成员。 2. 解释友元类:一个类可以声明另一个类为其友元,这样友元类就可以访问该类的私有和保护成员。 3. 注意:友元关系是单向的,不具有传递性(即A是B的友元,B是C的友元,并不意味A是C的友元)。 4. 友元破坏了封装性,因此应谨慎使用。 同时,我们将按照要求生成相关问题。 由于用户的问题中要求使用中文,所以整个回答用中文。 代码部分使用代码块格式。 注意:引用标识的使用。由于我们参考了C++的一般知识,但引用中并没有直接相关的内容,因此我们可以不添加引用标识,或者如果引用中的某些内容相关(比如静态成员)可以适当提及,但友元与静态成员无关。因此,我们主要根据知识回答,不强制添加引用标识。 但是,在回答中,我们可以提到友元函数与成员函数的区别(例如,成员函数有this指针,而友元函数没有),这时可以引用[4]中提到的静态成员函数也没有this指针,但注意友元函数不是静态成员函数,它们是非成员函数。因此,我们可以对比说明。 回答结构: 1. 友元函数 2. 友元类 3. 注意事项 4. 示例代码 5. 生成相关问题 示例代码将包括一个友元函数和一个友元类的例子。</think>### C++ 友元函数与友元类详解 #### 一、核心概念 友元(friend)是 C++ 中打破封装性的特殊机制,允许**外部函数或类访问私有成员**。主要特点: 1. **单向授权**:友元关系不可传递(A 授权 B ≠ B 自动授权 A) 2. **非继承性**:友元关系不被派生类继承 3. **精准控制**:可单独声明特定函数/类为友元 4. **语法形式**:使用 `friend` 关键字声明 #### 二、友元函数 **定义**:非成员函数访问类私有数据 ```cpp class BankAccount { private: double balance; // 私有成员 friend void audit(BankAccount&); // 友元声明 }; // 友元函数实现(无需 BankAccount::) void audit(BankAccount& acc) { std::cout << "审计访问余额: " << acc.balance; // 直接访问私有成员 } ``` **典型应用场景**: - 运算符重载(如 `<<` 流操作符) ```cpp friend std::ostream& operator<<(std::ostream& os, const MyClass& obj); ``` #### 三、友元类 **定义**:整个类访问另一类的私有成员 ```cpp class Sensor { private: int rawData; // 私有数据 friend class DataProcessor; // 友元类声明 }; class DataProcessor { public: void calibrate(Sensor& s) { s.rawData += 10; // 直接访问 Sensor 的私有成员 } }; ``` **关键限制**: - 友元关系**不对称**:`DataProcessor` 可访问 `Sensor`,反之不成立 - **不继承**:`DataProcessor` 的派生类不能访问 `Sensor` 私有成员 #### 四、注意事项与最佳实践 1. **封装破坏**:过度使用会导致代码耦合(建议优先用公有接口) 2. **前置声明**:友元类需提前声明 ```cpp class DataProcessor; // 前置声明 class Sensor { friend class DataProcessor; ... }; ``` 3. **模板特化**:友元声明在类模板中需特殊处理[^2] ```cpp template<typename T> class Box { friend void inspect<T>(Box<T>&); // 模板友元 }; ``` 4. **与静态成员对比**:友元函数无 `this` 指针,静态成员函数有类作用域但无 `this` 指针[^4] #### 五、典型错误示例 ```cpp class A { friend class B; int secret; }; class B { public: void leak(A a) { std::cout << a.secret; } // 合法 }; class C : public B { public: void fail(A a) { std::cout << a.secret; // 错误!友元关系不继承 } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值